@hyperframes/studio-server 0.7.15

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/createStudioApi.ts","../src/routes/projects.ts","../src/helpers/safePath.ts","../src/routes/storyboard.ts","../src/routes/files.ts","../src/helpers/mime.ts","../src/helpers/waveform.ts","../src/helpers/mediaValidation.ts","../src/helpers/backupJournal.ts","../src/helpers/finiteMutation.ts","../src/helpers/sourceMutation.ts","../src/routes/preview.ts","../src/helpers/subComposition.ts","../src/helpers/projectSignature.ts","../src/helpers/studioMotionRenderScript.ts","../src/helpers/hfIdPersist.ts","../src/routes/lint.ts","../src/routes/render.ts","../src/routes/thumbnail.ts","../src/helpers/manualEditsRenderScript.ts","../src/routes/waveform.ts","../src/routes/fonts.ts","../src/routes/registry.ts","../src/helpers/screenshotClip.ts"],"sourcesContent":["import { Hono } from \"hono\";\nimport type { StudioApiAdapter } from \"./types.js\";\nimport { registerProjectRoutes } from \"./routes/projects.js\";\nimport { registerStoryboardRoutes } from \"./routes/storyboard.js\";\nimport { registerFileRoutes } from \"./routes/files.js\";\nimport { registerPreviewRoutes } from \"./routes/preview.js\";\nimport { registerLintRoutes } from \"./routes/lint.js\";\nimport { registerRenderRoutes } from \"./routes/render.js\";\nimport { registerThumbnailRoutes } from \"./routes/thumbnail.js\";\nimport { registerWaveformRoutes } from \"./routes/waveform.js\";\nimport { registerFontRoutes } from \"./routes/fonts.js\";\nimport { registerRegistryRoutes } from \"./routes/registry.js\";\n\n/**\n * Create a Hono sub-app with all studio API routes.\n *\n * Both the vite dev server and CLI embedded server mount this app\n * under /api, each providing their own adapter for host-specific behavior.\n */\nexport function createStudioApi(adapter: StudioApiAdapter): Hono {\n const api = new Hono();\n\n registerProjectRoutes(api, adapter);\n registerStoryboardRoutes(api, adapter);\n registerFileRoutes(api, adapter);\n registerPreviewRoutes(api, adapter);\n registerLintRoutes(api, adapter);\n registerRenderRoutes(api, adapter);\n registerThumbnailRoutes(api, adapter);\n registerWaveformRoutes(api, adapter);\n registerFontRoutes(api);\n registerRegistryRoutes(api, adapter);\n\n return api;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { Hono } from \"hono\";\nimport type { StudioApiAdapter } from \"../types.js\";\nimport { isInHiddenOrVendorDir, walkDir } from \"../helpers/safePath.js\";\n\nconst COMPOSITION_ID_RE = /data-composition-id\\s*=/;\n\nasync function filterCompositionFiles(projectDir: string, files: string[]): Promise<string[]> {\n const htmlFiles = files.filter((f) => f.endsWith(\".html\") && !isInHiddenOrVendorDir(f));\n const checks = await Promise.all(\n htmlFiles.map(async (f) => {\n try {\n const content = await readFile(join(projectDir, f), \"utf-8\");\n return COMPOSITION_ID_RE.test(content);\n } catch {\n return false;\n }\n }),\n );\n return htmlFiles.filter((_, i) => checks[i]);\n}\n\nexport function registerProjectRoutes(api: Hono, adapter: StudioApiAdapter): void {\n // List all projects\n api.get(\"/projects\", async (c) => {\n const projects = await adapter.listProjects();\n return c.json({ projects });\n });\n\n // Resolve session to project (multi-project mode)\n api.get(\"/resolve-session/:sessionId\", async (c) => {\n if (!adapter.resolveSession) {\n return c.json({ error: \"not available\" }, 404);\n }\n const { sessionId } = c.req.param();\n const result = await adapter.resolveSession(sessionId);\n if (!result) return c.json({ error: \"Session not found\" }, 404);\n return c.json(result);\n });\n\n // Project file tree\n api.get(\"/projects/:id\", async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n const files = walkDir(project.dir);\n const compositions = await filterCompositionFiles(project.dir, files);\n return c.json({ id: project.id, dir: project.dir, title: project.title, files, compositions });\n });\n}\n","import { join } from \"node:path\";\nimport { readdirSync } from \"node:fs\";\n\n// `isSafePath` lives at the package root so non-studio-api layers (compiler,\n// CLI, engine) can share it without a backwards dependency on studio-api.\n// Re-exported here for back-compat with existing `../helpers/safePath.js` imports.\nexport { isSafePath, resolveWithinProject } from \"@hyperframes/core\";\n\nconst IGNORE_DIRS = new Set([\".thumbnails\", \"node_modules\", \".git\"]);\n\nfunction shouldIgnoreDir(rel: string): boolean {\n return rel === \".hyperframes/backup\";\n}\n\n/**\n * True when any directory segment of a relative path is a dot-directory or\n * node_modules. Projects that vendor tooling assets under dot-directories\n * (.hyperframes/, .cache/, …) ship example/preset HTML that must not surface\n * as project compositions or studio lint targets (#1384). The file tree is\n * deliberately not filtered — this only gates discovery.\n */\nexport function isInHiddenOrVendorDir(relPath: string): boolean {\n const segments = relPath.split(\"/\");\n return segments.slice(0, -1).some((seg) => seg.startsWith(\".\") || seg === \"node_modules\");\n}\n\n/** Recursively walk a directory and return relative file paths. */\nexport function walkDir(dir: string, prefix = \"\"): string[] {\n const files: string[] = [];\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const rel = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (IGNORE_DIRS.has(entry.name) || shouldIgnoreDir(rel)) continue;\n if (entry.isDirectory()) {\n files.push(...walkDir(join(dir, entry.name), rel));\n } else {\n files.push(rel);\n }\n }\n return files;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { Hono } from \"hono\";\nimport type { StudioApiAdapter } from \"../types.js\";\nimport { resolveWithinProject } from \"../helpers/safePath.js\";\nimport {\n parseStoryboard,\n SCRIPT_FILENAME,\n STORYBOARD_FILENAME,\n type StoryboardFrame,\n} from \"@hyperframes/core/storyboard\";\n\n/** A frame enriched with disk-resolution info the Studio needs to render tiles. */\ninterface ResolvedStoryboardFrame extends StoryboardFrame {\n /** Whether `src` resolves to an existing file inside the project. */\n srcExists: boolean;\n}\n\nfunction resolveFrames(projectDir: string, frames: StoryboardFrame[]): ResolvedStoryboardFrame[] {\n return frames.map((frame) => {\n let srcExists = false;\n if (frame.src) {\n const abs = resolveWithinProject(projectDir, frame.src);\n srcExists = abs ? existsSync(abs) : false;\n }\n return { ...frame, srcExists };\n });\n}\n\n/** Read the companion SCRIPT.md narration doc if it exists alongside the storyboard. */\nfunction readScript(projectDir: string): { exists: boolean; path: string; content: string } {\n const abs = resolveWithinProject(projectDir, SCRIPT_FILENAME);\n if (abs && existsSync(abs)) {\n try {\n return { exists: true, path: SCRIPT_FILENAME, content: readFileSync(abs, \"utf-8\") };\n } catch {\n /* fall through to absent */\n }\n }\n return { exists: false, path: SCRIPT_FILENAME, content: \"\" };\n}\n\nexport function registerStoryboardRoutes(api: Hono, adapter: StudioApiAdapter): void {\n // Parsed storyboard manifest for a project. Markdown (STORYBOARD.md) stays\n // canonical on disk; this returns the derived, normalized structure. When the\n // file is absent we return `exists: false` with empty frames rather than 404,\n // so the Studio can render an opt-in empty state.\n api.get(\"/projects/:id/storyboard\", async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n\n const abs = resolveWithinProject(project.dir, STORYBOARD_FILENAME);\n if (!abs || !existsSync(abs)) {\n return c.json({\n exists: false,\n path: STORYBOARD_FILENAME,\n globals: { extra: {} },\n frames: [],\n warnings: [],\n script: readScript(project.dir),\n });\n }\n\n let source: string;\n try {\n source = readFileSync(abs, \"utf-8\");\n } catch {\n return c.json({ error: \"failed to read storyboard\" }, 500);\n }\n\n const manifest = parseStoryboard(source);\n return c.json({\n exists: true,\n path: STORYBOARD_FILENAME,\n globals: manifest.globals,\n frames: resolveFrames(project.dir, manifest.frames),\n warnings: manifest.warnings,\n script: readScript(project.dir),\n });\n });\n}\n","// fallow-ignore-file code-duplication\n// executeGsapMutationRecast and executeGsapMutationAcorn are intentionally\n// parallel — two writers, same switch-case interface. Structural duplication\n// is load-bearing (both paths must remain testable in isolation).\nimport type { Hono } from \"hono\";\nimport { bodyLimit } from \"hono/body-limit\";\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n unlinkSync,\n rmSync,\n statSync,\n renameSync,\n readdirSync,\n} from \"node:fs\";\nimport { resolve, dirname, join } from \"node:path\";\nimport type { StudioApiAdapter } from \"../types.js\";\nimport { isAudioFile } from \"../helpers/mime.js\";\nimport { generateWaveformCache } from \"../helpers/waveform.js\";\nimport { validateUploadedMediaBuffer } from \"../helpers/mediaValidation.js\";\nimport { isSafePath, resolveWithinProject } from \"../helpers/safePath.js\";\nimport { backupPathForResponse, snapshotBeforeWrite } from \"../helpers/backupJournal.js\";\nimport {\n findUnsafeDomPatchValues,\n findUnsafeMutationValues,\n type UnsafeMutationValue,\n} from \"../helpers/finiteMutation.js\";\nimport type { GsapAnimation } from \"@hyperframes/parsers\";\nimport { classifyPropertyGroup } from \"@hyperframes/parsers/gsap-constants\";\nimport { parseGsapScriptAcorn } from \"@hyperframes/parsers/gsap-parser-acorn\";\nimport { unrollComputedTimeline } from \"@hyperframes/parsers\";\nimport {\n updateAnimationInScript,\n addAnimationToScript,\n removeAnimationFromScript,\n addKeyframeToScript,\n removeKeyframeFromScript,\n updateKeyframeInScript,\n convertToKeyframesFromScript,\n removeAllKeyframesFromScript,\n materializeKeyframesFromScript,\n unrollDynamicAnimations,\n setArcPathInScript,\n updateArcSegmentInScript,\n removeArcPathFromScript,\n addAnimationWithKeyframesToScript,\n splitAnimationsInScript,\n splitIntoPropertyGroupsFromScript,\n shiftPositionsInScript,\n scalePositionsInScript,\n} from \"@hyperframes/parsers/gsap-writer-acorn\";\nimport {\n removeElementFromHtml,\n patchElementInHtml,\n probeElementInSource,\n splitElementInHtml,\n isHTMLElement,\n type PatchOperation,\n} from \"../helpers/sourceMutation.js\";\nimport { parseHTML } from \"linkedom\";\n\n// ── Server cutover flag ─────────────────────────────────────────────────────\n\n/**\n * Mirror of the client STUDIO_SDK_CUTOVER_ENABLED flag for server-side writer\n * selection. When true, the acorn writer handles GSAP mutations; otherwise the\n * recast writer (gsapParser.ts) is used. Default false → recast.\n *\n * Enable with: STUDIO_SDK_CUTOVER_ENABLED=true (or =1)\n * Mirrors the client Vite env var name so one env switch flips both sides.\n */\nfunction isAcornGsapWriterEnabled(): boolean {\n const val = process.env[\"STUDIO_SDK_CUTOVER_ENABLED\"];\n return val === \"true\" || val === \"1\";\n}\n\n/**\n * Lazy-load gsapParser for write ops (recast-backed) — the default server writer.\n * The read path uses the browser-safe acorn parser; this loader is only needed\n * for the recast write path (the default when STUDIO_SDK_CUTOVER_ENABLED is off).\n */\nasync function loadGsapParser() {\n return import(\"@hyperframes/parsers/gsap-parser-recast\");\n}\n\n// ── Shared helpers ──────────────────────────────────────────────────────────\n\n/**\n * Resolve the project and file path from the request, validating safety.\n * Returns null (and sends an error response) if anything is invalid.\n */\ninterface RouteContext {\n req: {\n param: (name: string) => string;\n path: string;\n query: (name: string) => string | undefined;\n };\n json: (data: unknown, status?: number) => Response;\n}\n\n/** Resolve project + safe absolute path for any project-scoped route. */\nasync function resolveProjectPath(\n c: RouteContext,\n adapter: StudioApiAdapter,\n pathPrefix: (projectId: string) => string,\n opts?: { mustExist?: boolean },\n) {\n const id = c.req.param(\"id\");\n const project = await adapter.resolveProject(id);\n if (!project) {\n return { error: c.json({ error: \"not found\" }, 404) } as const;\n }\n\n const filePath = decodeURIComponent(c.req.path.replace(pathPrefix(project.id), \"\"));\n if (filePath.includes(\"\\0\")) {\n return { error: c.json({ error: \"forbidden\" }, 403) } as const;\n }\n\n const absPath = resolveWithinProject(project.dir, filePath);\n if (!absPath) {\n return { error: c.json({ error: \"forbidden\" }, 403) } as const;\n }\n\n if (opts?.mustExist && !existsSync(absPath)) {\n return { error: c.json({ error: \"not found\" }, 404) } as const;\n }\n\n return { project, filePath, absPath } as const;\n}\n\nfunction resolveProjectFile(\n c: RouteContext,\n adapter: StudioApiAdapter,\n opts?: { mustExist?: boolean },\n) {\n return resolveProjectPath(c, adapter, (id) => `/projects/${id}/files/`, opts);\n}\n\nfunction resolveFileMutationContext(c: RouteContext, adapter: StudioApiAdapter, operation: string) {\n return resolveProjectPath(c, adapter, (id) => `/projects/${id}/file-mutations/${operation}/`);\n}\n\ntype MutationTarget = {\n id?: string | null;\n hfId?: string;\n selector?: string;\n selectorIndex?: number;\n};\n\n/** Write `next` to `absPath` only if it differs from `original`, returning a standardized change response. */\nfunction writeIfChanged(\n c: RouteContext,\n projectDir: string,\n filePath: string,\n absPath: string,\n original: string,\n next: string,\n): Response {\n if (next === original) {\n return c.json({ ok: true, changed: false, content: original, path: filePath });\n }\n const backup = snapshotBeforeWrite(projectDir, absPath);\n if (backup.error) console.warn(`Failed to create backup for ${filePath}: ${backup.error}`);\n writeFileSync(absPath, next, \"utf-8\");\n return c.json({\n ok: true,\n changed: true,\n content: next,\n path: filePath,\n backupPath: backupPathForResponse(projectDir, backup.backupPath),\n });\n}\n\nfunction rejectUnsafeMutationValues(\n c: RouteContext,\n unsafeFields: UnsafeMutationValue[],\n): Response {\n return c.json(\n {\n error: \"mutation contains unsafe values\",\n fields: unsafeFields.map((field) => field.path),\n unsafeValues: unsafeFields,\n },\n 400,\n );\n}\n\n/**\n * Parse the request body and validate that `target` is present.\n * Returns `{ error }` if missing, or `{ target, body }` for the full parsed body.\n */\nasync function parseMutationBody<T extends { target?: MutationTarget }>(\n c: RouteContext & { req: { json(): Promise<unknown> } },\n): Promise<{ error: Response } | { target: MutationTarget; body: T }> {\n const body = (await (c.req as { json(): Promise<unknown> }).json().catch(() => null)) as T | null;\n if (!body?.target) {\n return { error: c.json({ error: \"target required\" }, 400) };\n }\n return { target: body.target, body };\n}\n\n/** Ensure the parent directory of a path exists. */\nfunction ensureDir(filePath: string) {\n const dir = dirname(filePath);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\n/**\n * Generate a copy name: foo.html → foo (copy).html → foo (copy 2).html\n */\nfunction generateCopyPath(projectDir: string, originalPath: string): string {\n const ext = originalPath.includes(\".\") ? \".\" + originalPath.split(\".\").pop() : \"\";\n const base = ext ? originalPath.slice(0, -ext.length) : originalPath;\n\n // If already a copy, increment the number\n const copyMatch = base.match(/ \\(copy(?: (\\d+))?\\)$/);\n const cleanBase = copyMatch ? base.slice(0, -copyMatch[0].length) : base;\n let num = copyMatch ? (copyMatch[1] ? parseInt(copyMatch[1]) + 1 : 2) : 1;\n\n let candidate = num === 1 ? `${cleanBase} (copy)${ext}` : `${cleanBase} (copy ${num})${ext}`;\n while (existsSync(resolve(projectDir, candidate))) {\n num++;\n candidate = `${cleanBase} (copy ${num})${ext}`;\n }\n\n return candidate;\n}\n\n/**\n * Walk a directory recursively and return all file paths matching a filter.\n */\nfunction walkFiles(dir: string, filter: (name: string) => boolean): string[] {\n const results: string[] = [];\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (entry.name === \"node_modules\" || entry.name === \".thumbnails\" || entry.name === \"renders\")\n continue;\n results.push(...walkFiles(full, filter));\n } else if (filter(entry.name)) {\n results.push(full);\n }\n }\n return results;\n}\n\n/**\n * After a rename, update all references to the old path in project files.\n * Scans HTML, CSS, JS, and JSON files for the old filename/path and replaces.\n */\nfunction updateReferences(projectDir: string, oldPath: string, newPath: string): number {\n const textFiles = walkFiles(projectDir, (name) =>\n /\\.(html|css|js|jsx|ts|tsx|json|mjs|cjs|md|mdx)$/i.test(name),\n );\n\n let updatedCount = 0;\n for (const file of textFiles) {\n const content = readFileSync(file, \"utf-8\");\n\n // Only replace full relative paths — never bare filenames, which can\n // corrupt unrelated content (e.g. \"logo.png\" inside \"my-logo.png\").\n if (!content.includes(oldPath)) continue;\n\n const updated = content.split(oldPath).join(newPath);\n if (updated !== content) {\n writeFileSync(file, updated, \"utf-8\");\n updatedCount++;\n }\n }\n return updatedCount;\n}\n\n// ── GSAP script extraction ──────────────────────────────────────────────────\n\n/**\n * Parse an HTML string with linkedom, locate the inline `<script>` that\n * contains GSAP timeline code, and return both its text content and a\n * function that replaces that script block and serialises back to HTML.\n */\nfunction extractGsapScriptBlock(html: string): {\n scriptText: string;\n document: Document;\n replaceScript: (newText: string) => string;\n} | null {\n const { document } = parseHTML(html);\n const scripts = [\n ...document.querySelectorAll(\"script:not([src])\"),\n ...Array.from(document.querySelectorAll(\"template\")).flatMap((tmpl) =>\n Array.from(tmpl.querySelectorAll(\"script:not([src])\")),\n ),\n ];\n for (const script of scripts) {\n const content = script.textContent || \"\";\n if (\n content.includes(\"gsap.timeline\") ||\n content.includes(\".set(\") ||\n content.includes(\".to(\")\n ) {\n return {\n scriptText: content,\n document,\n replaceScript(newText: string): string {\n script.textContent = newText;\n return document.toString();\n },\n };\n }\n }\n return null;\n}\n\nfunction stripStudioEditsFromTarget(document: Document, selector: string): number {\n if (!selector) return 0;\n let stripped = 0;\n try {\n for (const el of document.querySelectorAll(selector)) {\n if (!isHTMLElement(el)) continue;\n const htmlEl = el;\n let touched = false;\n // Manual path offset (--hf-studio-offset / translate) — a GSAP position tween\n // now owns position, so the stale offset channel must go.\n if (el.getAttribute(\"data-hf-studio-path-offset\")) {\n const originalTranslate = el.getAttribute(\"data-hf-studio-original-inline-translate\");\n htmlEl.style.removeProperty(\"--hf-studio-offset-x\");\n htmlEl.style.removeProperty(\"--hf-studio-offset-y\");\n if (originalTranslate) {\n htmlEl.style.setProperty(\"translate\", originalTranslate);\n } else {\n htmlEl.style.removeProperty(\"translate\");\n }\n el.removeAttribute(\"data-hf-studio-path-offset\");\n el.removeAttribute(\"data-hf-studio-original-translate\");\n el.removeAttribute(\"data-hf-studio-original-inline-translate\");\n touched = true;\n }\n // Manual rotation (--hf-studio-rotation / rotate) — likewise, a GSAP rotation\n // set/tween now owns rotation, so clear the legacy CSS-var channel.\n if (el.getAttribute(\"data-hf-studio-rotation\")) {\n const originalRotate = el.getAttribute(\"data-hf-studio-original-inline-rotate\");\n const originalOrigin = el.getAttribute(\"data-hf-studio-original-rotation-transform-origin\");\n htmlEl.style.removeProperty(\"--hf-studio-rotation\");\n if (originalRotate) {\n htmlEl.style.setProperty(\"rotate\", originalRotate);\n } else {\n htmlEl.style.removeProperty(\"rotate\");\n }\n if (originalOrigin) {\n htmlEl.style.setProperty(\"transform-origin\", originalOrigin);\n } else {\n htmlEl.style.removeProperty(\"transform-origin\");\n }\n el.removeAttribute(\"data-hf-studio-rotation\");\n el.removeAttribute(\"data-hf-studio-rotation-draft\");\n el.removeAttribute(\"data-hf-studio-original-rotate\");\n el.removeAttribute(\"data-hf-studio-original-inline-rotate\");\n el.removeAttribute(\"data-hf-studio-original-rotation-transform-origin\");\n touched = true;\n }\n if (touched) stripped++;\n }\n } catch {\n // Invalid selector — skip silently.\n }\n return stripped;\n}\n\n// A studio path-offset (--hf-studio-offset / data-hf-studio-path-offset) and a GSAP\n// position tween both drive translate — keeping both stacks the offsets (a gesture or\n// drag recorded over a stale offset plays shoved off-position). When a committed tween\n// writes a position property, the tween owns position, so the stale offset must go.\nfunction keyframesWritePosition(\n keyframes: Array<{ properties: Record<string, number | string> }>,\n): boolean {\n return keyframes.some((kf) =>\n Object.keys(kf.properties).some((k) => classifyPropertyGroup(k) === \"position\"),\n );\n}\n\n// A studio rotation edit (--hf-studio-rotation / data-hf-studio-rotation) and a GSAP\n// rotation tween both drive rotate — keeping both stacks them. When a committed keyframe\n// set writes a rotation property, the tween owns rotation, so the stale CSS-var channel\n// must go (the position twin of this is `keyframesWritePosition`).\nfunction keyframesWriteRotation(\n keyframes: Array<{ properties: Record<string, number | string> }>,\n): boolean {\n return keyframes.some((kf) =>\n Object.keys(kf.properties).some((k) => classifyPropertyGroup(k) === \"rotation\"),\n );\n}\n\nfunction lastKeyframeOpacity(kfs: GsapAnimation[\"keyframes\"]): number | string | undefined {\n if (!kfs) return undefined;\n for (let i = kfs.keyframes.length - 1; i >= 0; i--) {\n if (\"opacity\" in kfs.keyframes[i]!.properties) return kfs.keyframes[i]!.properties.opacity;\n }\n return undefined;\n}\n\nfunction resolveFinalOpacity(anim: GsapAnimation): number | null {\n if (anim.method === \"from\") return null;\n const raw = anim.keyframes ? lastKeyframeOpacity(anim.keyframes) : anim.properties.opacity;\n if (raw == null) return null;\n if (typeof raw === \"string\" && /^[+\\-*]=/.test(raw)) return null;\n const num = Number(raw);\n return Number.isFinite(num) && num !== 0 ? num : null;\n}\n\nfunction bakeVisibilityOnDelete(document: Document, anim: GsapAnimation): void {\n const opacity = resolveFinalOpacity(anim);\n if (opacity === null) return;\n try {\n for (const el of document.querySelectorAll(anim.targetSelector)) {\n if (isHTMLElement(el)) el.style.setProperty(\"opacity\", String(opacity));\n }\n } catch {\n // Invalid selector — skip silently.\n }\n}\n\n// ── GSAP mutation types ─────────────────────────────────────────────────────\n\ntype GsapMutationRequest =\n | {\n type: \"update-property\";\n animationId: string;\n property: string;\n value: number | string;\n }\n | {\n // Merge MULTIPLE properties into an animation in ONE call. A per-property\n // loop on a `set` can shift its group-derived id mid-way (e.g. adding `scale`\n // to a rotation set), 404-ing the next update; this lands them all at once.\n type: \"update-properties\";\n animationId: string;\n properties: Record<string, number | string>;\n }\n | {\n type: \"update-from-property\";\n animationId: string;\n property: string;\n value: number | string;\n }\n | {\n type: \"update-meta\";\n animationId: string;\n updates: {\n duration?: number;\n ease?: string;\n easeEach?: string;\n position?: number;\n resetKeyframeEases?: boolean;\n };\n }\n | {\n type: \"add\";\n targetSelector: string;\n method: \"to\" | \"from\" | \"set\" | \"fromTo\";\n position: number;\n duration?: number;\n ease?: string;\n properties: Record<string, number | string>;\n fromProperties?: Record<string, number | string>;\n /** Emit a base `gsap.set` (off-timeline, no keyframe marker) instead of `tl.set`. */\n global?: boolean;\n }\n | { type: \"delete\"; animationId: string; stripStudioEdits?: boolean }\n | {\n type: \"add-property\";\n animationId: string;\n property: string;\n defaultValue: number | string;\n }\n | {\n type: \"add-from-property\";\n animationId: string;\n property: string;\n defaultValue: number | string;\n }\n | { type: \"remove-property\"; animationId: string; property: string }\n | { type: \"remove-from-property\"; animationId: string; property: string }\n | {\n type: \"add-keyframe\";\n animationId: string;\n percentage: number;\n properties: Record<string, number | string>;\n ease?: string;\n backfillDefaults?: Record<string, number | string>;\n }\n | { type: \"remove-keyframe\"; animationId: string; percentage: number }\n | {\n type: \"update-keyframe\";\n animationId: string;\n percentage: number;\n properties: Record<string, number | string>;\n ease?: string;\n }\n | {\n type: \"convert-to-keyframes\";\n animationId: string;\n resolvedFromValues?: Record<string, number | string>;\n /** Duration (s) to give a converted static `set`, which has none. */\n duration?: number;\n }\n | { type: \"remove-all-keyframes\"; animationId: string }\n | {\n type: \"materialize-keyframes\";\n animationId: string;\n keyframes: Array<{\n percentage: number;\n properties: Record<string, number | string>;\n ease?: string;\n }>;\n easeEach?: string;\n resolvedSelector?: string;\n allElements?: Array<{\n selector: string;\n keyframes: Array<{ percentage: number; properties: Record<string, number | string> }>;\n easeEach?: string;\n }>;\n }\n | {\n type: \"set-arc-path\";\n animationId: string;\n enabled: boolean;\n autoRotate?: boolean | number;\n segments?: Array<{\n curviness: number;\n cp1?: { x: number; y: number };\n cp2?: { x: number; y: number };\n }>;\n }\n | {\n type: \"update-arc-segment\";\n animationId: string;\n segmentIndex: number;\n curviness?: number;\n cp1?: { x: number; y: number };\n cp2?: { x: number; y: number };\n }\n | {\n type: \"update-motion-path-point\";\n animationId: string;\n pointIndex: number;\n x: number;\n y: number;\n }\n | { type: \"add-motion-path-point\"; animationId: string; index: number; x: number; y: number }\n | { type: \"remove-motion-path-point\"; animationId: string; index: number }\n | {\n type: \"add-motion-path\";\n targetSelector: string;\n position: number;\n duration: number;\n x: number;\n y: number;\n ease?: string;\n }\n | { type: \"remove-arc-path\"; animationId: string }\n | {\n type: \"add-with-keyframes\";\n targetSelector: string;\n position: number;\n duration: number;\n keyframes: Array<{\n percentage: number;\n properties: Record<string, number | string>;\n ease?: string;\n auto?: boolean;\n }>;\n ease?: string;\n easeEach?: string;\n }\n | {\n type: \"replace-with-keyframes\";\n animationId: string;\n targetSelector: string;\n position: number;\n duration: number;\n keyframes: Array<{\n percentage: number;\n properties: Record<string, number | string>;\n ease?: string;\n auto?: boolean;\n }>;\n ease?: string;\n }\n | {\n type: \"split-animations\";\n originalId: string;\n newId: string;\n splitTime: number;\n elementStart: number;\n elementDuration: number;\n }\n | {\n type: \"split-into-property-groups\";\n animationId: string;\n }\n | {\n type: \"delete-all-for-selector\";\n targetSelector: string;\n }\n | {\n // Rewrite all top-level helper/loop constructs into literal tweens so\n // computed keyframes become directly editable (visual no-op).\n type: \"unroll-timeline\";\n }\n | {\n type: \"shift-positions\";\n targetSelector: string;\n delta: number;\n }\n | {\n type: \"scale-positions\";\n targetSelector: string;\n oldStart: number;\n oldDuration: number;\n newStart: number;\n newDuration: number;\n };\n\n// ── GSAP mutation executor ──────────────────────────────────────────────────\n\ntype GsapMutationResult = string | { script: string; skippedSelectors: string[] };\n\n// Mutations that can change a position tween's first keyframe (value/existence/timing)\n// and therefore require the pre-keyframe hold-`set`s to be re-synced afterwards.\n// `syncPositionHoldsBeforeKeyframes` rebuilds all `hf-hold` sets from scratch: it acts\n// on every tween that has keyframes whose first percentage carries a position prop and\n// whose start is > 0. So any mutation that creates such a tween, retargets it, or moves\n// its start across the t=0 boundary must trigger a re-sync.\nconst HOLD_SYNC_MUTATION_TYPES = new Set<string>([\n \"add-keyframe\",\n \"update-keyframe\",\n \"remove-keyframe\",\n \"remove-all-keyframes\",\n \"add-with-keyframes\",\n \"replace-with-keyframes\",\n \"convert-to-keyframes\",\n \"materialize-keyframes\",\n \"update-motion-path-point\",\n \"add-motion-path-point\",\n \"remove-motion-path-point\",\n // Authors a fresh motionPath tween whose parsed first keyframe is (0,0); if it lands\n // at position > 0 the element snaps home at t=0 without a pre-tween hold-`set`.\n \"add-motion-path\",\n // Can move a tween's `position` (start) across the t=0 boundary, which flips whether a\n // keyframed position tween needs a hold (started at 0 → moved later, or vice versa).\n \"update-meta\",\n // Time-shift / time-scale tweens, which can move a keyframed position tween's start\n // across t=0, flipping hold need; stale holds are not repositioned by these ops.\n \"shift-positions\",\n \"scale-positions\",\n // Retargets keyframed position tweens to a cloned element's selector; the old hold is\n // keyed to the prior selector, so holds must be rebuilt for the new target.\n \"split-animations\",\n \"delete\",\n \"delete-all-for-selector\",\n]);\n\nasync function executeGsapMutation(\n body: GsapMutationRequest,\n block: NonNullable<ReturnType<typeof extractGsapScriptBlock>>,\n respond: (data: unknown, status?: number) => Response,\n): Promise<GsapMutationResult | Response> {\n // When the server cutover flag is enabled, delegate to the acorn writer;\n // otherwise use the recast writer (gsapParser.ts) as the default.\n if (!isAcornGsapWriterEnabled()) {\n return executeGsapMutationRecast(body, block, respond);\n }\n return executeGsapMutationAcorn(body, block, respond);\n}\n\nfunction executeGsapMutationAcorn(\n body: GsapMutationRequest,\n block: NonNullable<ReturnType<typeof extractGsapScriptBlock>>,\n respond: (data: unknown, status?: number) => Response,\n): GsapMutationResult | Response {\n function requireAnimation(\n scriptText: string,\n animationId: string,\n ): { anim: GsapAnimation } | { err: Response } {\n const parsed = parseGsapScriptAcorn(scriptText);\n const anim = parsed.animations.find((a) => a.id === animationId);\n if (!anim) return { err: respond({ error: \"animation not found\" }, 404) };\n return { anim };\n }\n\n function requireFromToAnimation(\n scriptText: string,\n animationId: string,\n ): { anim: GsapAnimation } | { err: Response } {\n const result = requireAnimation(scriptText, animationId);\n if (\"err\" in result) return result;\n if (result.anim.method !== \"fromTo\")\n return { err: respond({ error: \"animation is not a fromTo\" }, 400) };\n return result;\n }\n\n switch (body.type) {\n case \"update-property\":\n case \"add-property\": {\n const r = requireAnimation(block.scriptText, body.animationId);\n if (\"err\" in r) return r.err;\n const val = body.type === \"update-property\" ? body.value : body.defaultValue;\n return updateAnimationInScript(block.scriptText, body.animationId, {\n properties: { ...r.anim.properties, [body.property]: val },\n });\n }\n case \"update-properties\": {\n const r = requireAnimation(block.scriptText, body.animationId);\n if (\"err\" in r) return r.err;\n return updateAnimationInScript(block.scriptText, body.animationId, {\n properties: { ...r.anim.properties, ...body.properties },\n });\n }\n case \"update-from-property\":\n case \"add-from-property\": {\n const r = requireFromToAnimation(block.scriptText, body.animationId);\n if (\"err\" in r) return r.err;\n const val = body.type === \"update-from-property\" ? body.value : body.defaultValue;\n return updateAnimationInScript(block.scriptText, body.animationId, {\n fromProperties: { ...(r.anim.fromProperties ?? {}), [body.property]: val },\n });\n }\n case \"update-meta\": {\n return updateAnimationInScript(block.scriptText, body.animationId, body.updates);\n }\n case \"add\": {\n if (body.fromProperties && body.method !== \"fromTo\") {\n return respond({ error: \"fromProperties is only valid for method=fromTo\" }, 400);\n }\n const result = addAnimationToScript(block.scriptText, {\n targetSelector: body.targetSelector,\n method: body.method,\n position: body.position,\n duration: body.duration,\n ease: body.ease,\n properties: body.properties,\n fromProperties: body.fromProperties,\n ...(body.global ? { global: true } : {}),\n });\n return result.script;\n }\n case \"delete\": {\n const delTarget = requireAnimation(block.scriptText, body.animationId);\n if (!(\"err\" in delTarget) && body.stripStudioEdits) {\n stripStudioEditsFromTarget(block.document, delTarget.anim.targetSelector);\n bakeVisibilityOnDelete(block.document, delTarget.anim);\n }\n return removeAnimationFromScript(block.scriptText, body.animationId);\n }\n case \"delete-all-for-selector\": {\n const parsed = parseGsapScriptAcorn(block.scriptText);\n const matching = parsed.animations.filter((a) => a.targetSelector === body.targetSelector);\n if (matching.length === 0) return block.scriptText;\n stripStudioEditsFromTarget(block.document, body.targetSelector);\n let script = block.scriptText;\n for (const anim of matching.reverse()) {\n script = removeAnimationFromScript(script, anim.id);\n }\n return script;\n }\n case \"remove-property\": {\n const r = requireAnimation(block.scriptText, body.animationId);\n if (\"err\" in r) return r.err;\n const filtered = { ...r.anim.properties };\n delete filtered[body.property];\n return updateAnimationInScript(block.scriptText, body.animationId, {\n properties: filtered,\n });\n }\n case \"remove-from-property\": {\n const r = requireFromToAnimation(block.scriptText, body.animationId);\n if (\"err\" in r) return r.err;\n const filtered = { ...(r.anim.fromProperties ?? {}) };\n delete filtered[body.property];\n return updateAnimationInScript(block.scriptText, body.animationId, {\n fromProperties: filtered,\n });\n }\n case \"add-keyframe\": {\n return addKeyframeToScript(\n block.scriptText,\n body.animationId,\n body.percentage,\n body.properties,\n body.ease,\n body.backfillDefaults,\n );\n }\n case \"remove-keyframe\": {\n return removeKeyframeFromScript(block.scriptText, body.animationId, body.percentage);\n }\n case \"update-keyframe\": {\n return updateKeyframeInScript(\n block.scriptText,\n body.animationId,\n body.percentage,\n body.properties,\n body.ease,\n );\n }\n case \"convert-to-keyframes\": {\n return convertToKeyframesFromScript(\n block.scriptText,\n body.animationId,\n body.resolvedFromValues,\n body.duration,\n );\n }\n case \"remove-all-keyframes\": {\n const preCollapse = requireAnimation(block.scriptText, body.animationId);\n if (!(\"err\" in preCollapse)) {\n bakeVisibilityOnDelete(block.document, preCollapse.anim);\n }\n return removeAllKeyframesFromScript(block.scriptText, body.animationId);\n }\n case \"materialize-keyframes\": {\n if (body.allElements && body.allElements.length > 0) {\n return unrollDynamicAnimations(block.scriptText, body.animationId, body.allElements);\n }\n return materializeKeyframesFromScript(\n block.scriptText,\n body.animationId,\n body.keyframes,\n body.easeEach,\n body.resolvedSelector,\n );\n }\n case \"set-arc-path\": {\n return setArcPathInScript(block.scriptText, body.animationId, {\n enabled: body.enabled,\n autoRotate: body.autoRotate ?? false,\n segments: body.segments ?? [],\n });\n }\n case \"update-arc-segment\": {\n return updateArcSegmentInScript(block.scriptText, body.animationId, body.segmentIndex, {\n ...(body.curviness !== undefined ? { curviness: body.curviness } : {}),\n ...(body.cp1 ? { cp1: body.cp1 } : {}),\n ...(body.cp2 ? { cp2: body.cp2 } : {}),\n });\n }\n case \"remove-arc-path\": {\n return removeArcPathFromScript(block.scriptText, body.animationId);\n }\n case \"add-with-keyframes\": {\n const result = addAnimationWithKeyframesToScript(\n block.scriptText,\n body.targetSelector,\n body.position,\n body.duration,\n body.keyframes,\n body.ease,\n body.easeEach,\n );\n return result.script;\n }\n case \"replace-with-keyframes\": {\n const script = removeAnimationFromScript(block.scriptText, body.animationId);\n const added = addAnimationWithKeyframesToScript(\n script,\n body.targetSelector,\n body.position,\n body.duration,\n body.keyframes,\n body.ease,\n );\n return added.script;\n }\n case \"split-animations\": {\n if (\n typeof body.originalId !== \"string\" ||\n !body.originalId ||\n typeof body.newId !== \"string\" ||\n !body.newId ||\n typeof body.splitTime !== \"number\" ||\n !Number.isFinite(body.splitTime) ||\n typeof body.elementStart !== \"number\" ||\n !Number.isFinite(body.elementStart) ||\n typeof body.elementDuration !== \"number\" ||\n !Number.isFinite(body.elementDuration) ||\n body.elementDuration <= 0\n ) {\n return respond(\n {\n error:\n \"split-animations requires originalId, newId (non-empty strings), splitTime, elementStart (finite numbers), and elementDuration (positive number)\",\n },\n 400,\n );\n }\n return splitAnimationsInScript(block.scriptText, {\n originalId: body.originalId,\n newId: body.newId,\n splitTime: body.splitTime,\n elementStart: body.elementStart,\n elementDuration: body.elementDuration,\n });\n }\n case \"split-into-property-groups\": {\n const result = splitIntoPropertyGroupsFromScript(block.scriptText, body.animationId);\n return result.script;\n }\n case \"unroll-timeline\": {\n return unrollComputedTimeline(block.scriptText);\n }\n case \"shift-positions\": {\n const { targetSelector, delta } = body;\n if (!targetSelector || !Number.isFinite(delta) || delta === 0) return block.scriptText;\n return shiftPositionsInScript(block.scriptText, targetSelector, delta);\n }\n case \"scale-positions\": {\n const { targetSelector, oldStart, oldDuration, newStart, newDuration } = body;\n if (\n !targetSelector ||\n !Number.isFinite(oldStart) ||\n !Number.isFinite(oldDuration) ||\n !Number.isFinite(newStart) ||\n !Number.isFinite(newDuration) ||\n oldDuration <= 0 ||\n newDuration <= 0\n )\n return block.scriptText;\n if (oldStart === newStart && oldDuration === newDuration) return block.scriptText;\n return scalePositionsInScript(\n block.scriptText,\n targetSelector,\n oldStart,\n oldDuration,\n newStart,\n newDuration,\n );\n }\n default:\n return respond({ error: `unknown mutation type: ${(body as { type: string }).type}` }, 400);\n }\n}\n\nasync function executeGsapMutationRecast(\n body: GsapMutationRequest,\n block: NonNullable<ReturnType<typeof extractGsapScriptBlock>>,\n respond: (data: unknown, status?: number) => Response,\n): Promise<GsapMutationResult | Response> {\n const parser = await loadGsapParser();\n const {\n updateAnimationInScript,\n addAnimationToScript,\n removeAnimationFromScript,\n addKeyframeToScript,\n removeKeyframeFromScript,\n updateKeyframeInScript,\n convertToKeyframesInScript,\n removeAllKeyframesFromScript,\n materializeKeyframesInScript,\n unrollDynamicAnimations,\n setArcPathInScript,\n updateArcSegmentInScript,\n updateMotionPathPointInScript,\n addMotionPathPointInScript,\n removeMotionPathPointInScript,\n addMotionPathToScript,\n removeArcPathFromScript,\n addAnimationWithKeyframesToScript,\n splitAnimationsInScript,\n splitIntoPropertyGroups,\n } = parser;\n\n function requireAnimation(\n scriptText: string,\n animationId: string,\n ): { anim: GsapAnimation } | { err: Response } {\n const parsed = parseGsapScriptAcorn(scriptText);\n const anim = parsed.animations.find((a) => a.id === animationId);\n if (!anim) return { err: respond({ error: \"animation not found\" }, 404) };\n return { anim };\n }\n\n function requireFromToAnimation(\n scriptText: string,\n animationId: string,\n ): { anim: GsapAnimation } | { err: Response } {\n const result = requireAnimation(scriptText, animationId);\n if (\"err\" in result) return result;\n if (result.anim.method !== \"fromTo\")\n return { err: respond({ error: \"animation is not a fromTo\" }, 400) };\n return result;\n }\n\n switch (body.type) {\n case \"update-property\":\n case \"add-property\": {\n const r = requireAnimation(block.scriptText, body.animationId);\n if (\"err\" in r) return r.err;\n const val = body.type === \"update-property\" ? body.value : body.defaultValue;\n return updateAnimationInScript(block.scriptText, body.animationId, {\n properties: { ...r.anim.properties, [body.property]: val },\n });\n }\n case \"update-properties\": {\n const r = requireAnimation(block.scriptText, body.animationId);\n if (\"err\" in r) return r.err;\n return updateAnimationInScript(block.scriptText, body.animationId, {\n properties: { ...r.anim.properties, ...body.properties },\n });\n }\n case \"update-from-property\":\n case \"add-from-property\": {\n const r = requireFromToAnimation(block.scriptText, body.animationId);\n if (\"err\" in r) return r.err;\n const val = body.type === \"update-from-property\" ? body.value : body.defaultValue;\n return updateAnimationInScript(block.scriptText, body.animationId, {\n fromProperties: { ...(r.anim.fromProperties ?? {}), [body.property]: val },\n });\n }\n case \"update-meta\": {\n return updateAnimationInScript(block.scriptText, body.animationId, body.updates);\n }\n case \"add\": {\n if (body.fromProperties && body.method !== \"fromTo\") {\n return respond({ error: \"fromProperties is only valid for method=fromTo\" }, 400);\n }\n // A new position/rotation animation owns that channel — strip the matching\n // legacy studio CSS var (--hf-studio-offset / --hf-studio-rotation) so it can't\n // double with the tween, matching add-with-keyframes/replace-with-keyframes.\n if (\n Object.keys(body.properties).some((k) => {\n const group = classifyPropertyGroup(k);\n return group === \"position\" || group === \"rotation\";\n })\n ) {\n stripStudioEditsFromTarget(block.document, body.targetSelector);\n }\n const result = addAnimationToScript(block.scriptText, {\n targetSelector: body.targetSelector,\n method: body.method,\n position: body.position,\n duration: body.duration,\n ease: body.ease,\n properties: body.properties,\n fromProperties: body.fromProperties,\n ...(body.global ? { global: true } : {}),\n });\n return result.script;\n }\n case \"delete\": {\n const delTarget = requireAnimation(block.scriptText, body.animationId);\n if (!(\"err\" in delTarget) && body.stripStudioEdits) {\n stripStudioEditsFromTarget(block.document, delTarget.anim.targetSelector);\n bakeVisibilityOnDelete(block.document, delTarget.anim);\n }\n return removeAnimationFromScript(block.scriptText, body.animationId);\n }\n case \"delete-all-for-selector\": {\n const parsed = parseGsapScriptAcorn(block.scriptText);\n const matching = parsed.animations.filter((a) => a.targetSelector === body.targetSelector);\n if (matching.length === 0) return block.scriptText;\n stripStudioEditsFromTarget(block.document, body.targetSelector);\n let script = block.scriptText;\n for (const anim of matching.reverse()) {\n script = removeAnimationFromScript(script, anim.id);\n }\n return script;\n }\n case \"remove-property\": {\n const r = requireAnimation(block.scriptText, body.animationId);\n if (\"err\" in r) return r.err;\n const filtered = { ...r.anim.properties };\n delete filtered[body.property];\n return updateAnimationInScript(block.scriptText, body.animationId, {\n properties: filtered,\n });\n }\n case \"remove-from-property\": {\n const r = requireFromToAnimation(block.scriptText, body.animationId);\n if (\"err\" in r) return r.err;\n const filtered = { ...(r.anim.fromProperties ?? {}) };\n delete filtered[body.property];\n return updateAnimationInScript(block.scriptText, body.animationId, {\n fromProperties: filtered,\n });\n }\n case \"add-keyframe\": {\n return addKeyframeToScript(\n block.scriptText,\n body.animationId,\n body.percentage,\n body.properties,\n body.ease,\n body.backfillDefaults,\n );\n }\n case \"remove-keyframe\": {\n return removeKeyframeFromScript(block.scriptText, body.animationId, body.percentage);\n }\n case \"update-keyframe\": {\n return updateKeyframeInScript(\n block.scriptText,\n body.animationId,\n body.percentage,\n body.properties,\n body.ease,\n );\n }\n case \"convert-to-keyframes\": {\n return convertToKeyframesInScript(\n block.scriptText,\n body.animationId,\n body.resolvedFromValues,\n body.duration,\n );\n }\n case \"remove-all-keyframes\": {\n const preCollapse = requireAnimation(block.scriptText, body.animationId);\n if (!(\"err\" in preCollapse)) {\n bakeVisibilityOnDelete(block.document, preCollapse.anim);\n }\n return removeAllKeyframesFromScript(block.scriptText, body.animationId);\n }\n case \"materialize-keyframes\": {\n if (body.allElements && body.allElements.length > 0) {\n return unrollDynamicAnimations(block.scriptText, body.animationId, body.allElements);\n }\n return materializeKeyframesInScript(\n block.scriptText,\n body.animationId,\n body.keyframes,\n body.easeEach,\n body.resolvedSelector,\n );\n }\n case \"set-arc-path\": {\n return setArcPathInScript(block.scriptText, body.animationId, {\n enabled: body.enabled,\n autoRotate: body.autoRotate ?? false,\n segments: body.segments ?? [],\n });\n }\n case \"update-arc-segment\": {\n return updateArcSegmentInScript(block.scriptText, body.animationId, body.segmentIndex, {\n ...(body.curviness !== undefined ? { curviness: body.curviness } : {}),\n ...(body.cp1 ? { cp1: body.cp1 } : {}),\n ...(body.cp2 ? { cp2: body.cp2 } : {}),\n });\n }\n case \"update-motion-path-point\": {\n return updateMotionPathPointInScript(block.scriptText, body.animationId, body.pointIndex, {\n x: body.x,\n y: body.y,\n });\n }\n case \"add-motion-path-point\": {\n return addMotionPathPointInScript(block.scriptText, body.animationId, body.index, {\n x: body.x,\n y: body.y,\n });\n }\n case \"remove-motion-path-point\": {\n return removeMotionPathPointInScript(block.scriptText, body.animationId, body.index);\n }\n case \"add-motion-path\": {\n const result = addMotionPathToScript(\n block.scriptText,\n body.targetSelector,\n body.position,\n body.duration,\n { x: body.x, y: body.y },\n body.ease,\n );\n return result.script;\n }\n case \"remove-arc-path\": {\n return removeArcPathFromScript(block.scriptText, body.animationId);\n }\n case \"add-with-keyframes\": {\n if (keyframesWritePosition(body.keyframes) || keyframesWriteRotation(body.keyframes)) {\n stripStudioEditsFromTarget(block.document, body.targetSelector);\n }\n const result = addAnimationWithKeyframesToScript(\n block.scriptText,\n body.targetSelector,\n body.position,\n body.duration,\n body.keyframes,\n body.ease,\n );\n return result.script;\n }\n case \"replace-with-keyframes\": {\n if (keyframesWritePosition(body.keyframes) || keyframesWriteRotation(body.keyframes)) {\n stripStudioEditsFromTarget(block.document, body.targetSelector);\n }\n const script = removeAnimationFromScript(block.scriptText, body.animationId);\n const added = addAnimationWithKeyframesToScript(\n script,\n body.targetSelector,\n body.position,\n body.duration,\n body.keyframes,\n body.ease,\n );\n return added.script;\n }\n case \"split-animations\": {\n if (\n typeof body.originalId !== \"string\" ||\n !body.originalId ||\n typeof body.newId !== \"string\" ||\n !body.newId ||\n typeof body.splitTime !== \"number\" ||\n !Number.isFinite(body.splitTime) ||\n typeof body.elementStart !== \"number\" ||\n !Number.isFinite(body.elementStart) ||\n typeof body.elementDuration !== \"number\" ||\n !Number.isFinite(body.elementDuration) ||\n body.elementDuration <= 0\n ) {\n return respond(\n {\n error:\n \"split-animations requires originalId, newId (non-empty strings), splitTime, elementStart (finite numbers), and elementDuration (positive number)\",\n },\n 400,\n );\n }\n return splitAnimationsInScript(block.scriptText, {\n originalId: body.originalId,\n newId: body.newId,\n splitTime: body.splitTime,\n elementStart: body.elementStart,\n elementDuration: body.elementDuration,\n });\n }\n case \"split-into-property-groups\": {\n const result = splitIntoPropertyGroups(block.scriptText, body.animationId);\n return result.script;\n }\n case \"unroll-timeline\": {\n return unrollComputedTimeline(block.scriptText);\n }\n case \"shift-positions\": {\n const { targetSelector, delta } = body;\n if (!targetSelector || !Number.isFinite(delta) || delta === 0) return block.scriptText;\n const { shiftPositionsInScript } = parser;\n return shiftPositionsInScript(block.scriptText, targetSelector, delta);\n }\n case \"scale-positions\": {\n const { targetSelector, oldStart, oldDuration, newStart, newDuration } = body;\n if (\n !targetSelector ||\n !Number.isFinite(oldStart) ||\n !Number.isFinite(oldDuration) ||\n !Number.isFinite(newStart) ||\n !Number.isFinite(newDuration) ||\n oldDuration <= 0 ||\n newDuration <= 0\n )\n return block.scriptText;\n if (oldStart === newStart && oldDuration === newDuration) return block.scriptText;\n const { scalePositionsInScript } = parser;\n return scalePositionsInScript(\n block.scriptText,\n targetSelector,\n oldStart,\n oldDuration,\n newStart,\n newDuration,\n );\n }\n default:\n return respond({ error: `unknown mutation type: ${(body as { type: string }).type}` }, 400);\n }\n}\n\n// ── Upload file processing ──────────────────────────────────────────────────\n\nasync function processUploadedFiles(\n formData: FormData,\n targetDir: string,\n projectDir: string,\n): Promise<{\n uploaded: string[];\n skipped: string[];\n invalid: Array<{ name: string; reason: string }>;\n}> {\n const MAX_UPLOAD_BYTES = 500 * 1024 * 1024; // 500 MB per file\n const uploaded: string[] = [];\n const skipped: string[] = [];\n const invalid: Array<{ name: string; reason: string }> = [];\n\n // @types/node v25 narrows the ambient `FormData.entries()` to\n // `[string, string]` in workspaces where another dep declares an\n // `onmessage` global (it trips the worker branch of v25's conditional\n // File type). At runtime the value is still `File | string` — cast the\n // iterator so the rest of this block keeps type-checking on every\n // bun-install layout (hoisted on Windows surfaces this; isolated on\n // Linux happens to keep v24 in scope).\n type FileLike = {\n readonly name: string;\n readonly size: number;\n arrayBuffer(): Promise<ArrayBuffer>;\n };\n const entries = formData.entries() as unknown as Iterable<[string, FileLike | string]>;\n\n // Derive the subdirectory prefix from targetDir relative to projectDir\n const subDir = targetDir === projectDir ? \"\" : targetDir.slice(projectDir.length + 1);\n\n for (const [, value] of entries) {\n if (typeof value === \"string\") continue;\n\n // Strip path separators — browsers may include directory components\n const name = value.name.split(\"/\").pop()?.split(\"\\\\\").pop() ?? \"\";\n if (!name || name.includes(\"\\0\") || name.includes(\"..\")) continue;\n\n // Reject individual files that exceed the size limit\n if (value.size > MAX_UPLOAD_BYTES) {\n skipped.push(name);\n continue;\n }\n\n const destPath = resolve(targetDir, name);\n if (!isSafePath(projectDir, destPath)) continue;\n\n // Don't overwrite — append (2), (3), etc.\n let finalPath = destPath;\n let finalName = name;\n if (existsSync(finalPath)) {\n // Handle dotfiles correctly: .gitignore → ext=\"\", base=\".gitignore\"\n const dotIdx = name.indexOf(\".\", name.startsWith(\".\") ? 1 : 0);\n const ext = dotIdx > 0 ? name.slice(dotIdx) : \"\";\n const base = dotIdx > 0 ? name.slice(0, dotIdx) : name;\n let n = 2;\n const MAX_COPY_INDEX = 10000;\n while (n < MAX_COPY_INDEX && existsSync(resolve(targetDir, `${base} (${n})${ext}`))) n++;\n if (n >= MAX_COPY_INDEX) {\n skipped.push(name);\n continue;\n }\n finalName = `${base} (${n})${ext}`;\n finalPath = resolve(targetDir, finalName);\n }\n\n const buffer = Buffer.from(await value.arrayBuffer());\n const validation = validateUploadedMediaBuffer(finalName, buffer);\n if (!validation.ok) {\n invalid.push({ name: finalName, reason: validation.reason });\n continue;\n }\n\n writeFileSync(finalPath, buffer);\n const relativePath = subDir ? join(subDir, finalName) : finalName;\n uploaded.push(relativePath);\n if (isAudioFile(finalName)) {\n generateWaveformCache(projectDir, relativePath).catch(() => {});\n }\n }\n\n return { uploaded, skipped, invalid };\n}\n\n// ── Route registration ──────────────────────────────────────────────────────\n\nexport function registerFileRoutes(api: Hono, adapter: StudioApiAdapter): void {\n // ── Read ──\n\n api.get(\"/projects/:id/files/*\", async (c) => {\n const res = await resolveProjectFile(c, adapter);\n if (\"error\" in res) return res.error;\n\n if (!existsSync(res.absPath)) {\n if (c.req.query(\"optional\") === \"1\") {\n return c.json({ filename: res.filePath, content: \"\" });\n }\n return c.json({ error: \"not found\" }, 404);\n }\n\n const content = readFileSync(res.absPath, \"utf-8\");\n return c.json({ filename: res.filePath, content });\n });\n\n // ── Write (overwrite) ──\n\n api.put(\"/projects/:id/files/*\", async (c) => {\n const res = await resolveProjectFile(c, adapter);\n if (\"error\" in res) return res.error;\n\n ensureDir(res.absPath);\n const body = await c.req.text();\n const backup = snapshotBeforeWrite(res.project.dir, res.absPath);\n if (backup.error) console.warn(`Failed to create backup for ${res.filePath}: ${backup.error}`);\n writeFileSync(res.absPath, body, \"utf-8\");\n\n return c.json({\n ok: true,\n path: res.filePath,\n backupPath: backupPathForResponse(res.project.dir, backup.backupPath),\n });\n });\n\n // ── Create (fail if exists) ──\n\n api.post(\"/projects/:id/files/*\", async (c) => {\n const res = await resolveProjectFile(c, adapter);\n if (\"error\" in res) return res.error;\n\n if (existsSync(res.absPath)) {\n return c.json({ error: \"already exists\" }, 409);\n }\n\n ensureDir(res.absPath);\n const body = await c.req.text().catch(() => \"\");\n writeFileSync(res.absPath, body, \"utf-8\");\n\n return c.json({ ok: true, path: res.filePath }, 201);\n });\n\n // ── Delete ──\n\n api.delete(\"/projects/:id/files/*\", async (c) => {\n const res = await resolveProjectFile(c, adapter, { mustExist: true });\n if (\"error\" in res) return res.error;\n\n const stat = statSync(res.absPath);\n const backup = snapshotBeforeWrite(res.project.dir, res.absPath);\n if (backup.error) console.warn(`Failed to create backup for ${res.filePath}: ${backup.error}`);\n if (stat.isDirectory()) {\n rmSync(res.absPath, { recursive: true });\n } else {\n unlinkSync(res.absPath);\n }\n\n return c.json({\n ok: true,\n backupPath: backupPathForResponse(res.project.dir, backup.backupPath),\n });\n });\n\n api.post(\"/projects/:id/file-mutations/remove-element/*\", async (c) => {\n const ctx = await resolveFileMutationContext(c, adapter, \"remove-element\");\n if (\"error\" in ctx) return ctx.error;\n\n if (!existsSync(ctx.absPath)) {\n return c.json({ error: \"not found\" }, 404);\n }\n\n const parsed = await parseMutationBody<{ target?: MutationTarget }>(c);\n if (\"error\" in parsed) return parsed.error;\n\n const originalContent = readFileSync(ctx.absPath, \"utf-8\");\n return writeIfChanged(\n c,\n ctx.project.dir,\n ctx.filePath,\n ctx.absPath,\n originalContent,\n removeElementFromHtml(originalContent, parsed.target),\n );\n });\n\n api.post(\"/projects/:id/file-mutations/split-element/*\", async (c) => {\n const ctx = await resolveFileMutationContext(c, adapter, \"split-element\");\n if (\"error\" in ctx) return ctx.error;\n\n const parsed = await parseMutationBody<{\n target?: { id?: string; selector?: string; selectorIndex?: number };\n splitTime?: number;\n newId?: string;\n elementStart?: number;\n elementDuration?: number;\n }>(c);\n if (\"error\" in parsed) return parsed.error;\n if (typeof parsed.body.splitTime !== \"number\" || !parsed.body.newId) {\n return c.json({ error: \"target, splitTime, and newId required\" }, 400);\n }\n const fallbackTiming =\n typeof parsed.body.elementStart === \"number\" &&\n typeof parsed.body.elementDuration === \"number\"\n ? { start: parsed.body.elementStart, duration: parsed.body.elementDuration }\n : undefined;\n\n let originalContent: string;\n try {\n originalContent = readFileSync(ctx.absPath, \"utf-8\");\n } catch {\n return c.json({ error: \"not found\" }, 404);\n }\n const result = splitElementInHtml(\n originalContent,\n parsed.target,\n parsed.body.splitTime,\n parsed.body.newId,\n fallbackTiming,\n );\n if (!result.matched) {\n return c.json({ ok: false, changed: false, content: originalContent, path: ctx.filePath });\n }\n const backup = snapshotBeforeWrite(ctx.project.dir, ctx.absPath);\n if (backup.error) console.warn(`Failed to create backup for ${ctx.filePath}: ${backup.error}`);\n writeFileSync(ctx.absPath, result.html, \"utf-8\");\n return c.json({\n ok: true,\n changed: true,\n content: result.html,\n newId: result.newId,\n path: ctx.filePath,\n backupPath: backupPathForResponse(ctx.project.dir, backup.backupPath),\n });\n });\n\n api.post(\"/projects/:id/file-mutations/patch-element/*\", async (c) => {\n const ctx = await resolveFileMutationContext(c, adapter, \"patch-element\");\n if (\"error\" in ctx) return ctx.error;\n\n const parsed = await parseMutationBody<{\n target?: MutationTarget;\n operations?: PatchOperation[];\n }>(c);\n if (\"error\" in parsed) return parsed.error;\n if (!Array.isArray(parsed.body.operations) || parsed.body.operations.length === 0) {\n return c.json({ error: \"target and operations required\" }, 400);\n }\n const unsafeFields = findUnsafeDomPatchValues(parsed.body);\n if (unsafeFields.length > 0) {\n return rejectUnsafeMutationValues(c, unsafeFields);\n }\n\n let originalContent: string;\n try {\n originalContent = readFileSync(ctx.absPath, \"utf-8\");\n } catch {\n return c.json({ error: \"not found\" }, 404);\n }\n const { html: patched, matched } = patchElementInHtml(\n originalContent,\n parsed.target,\n parsed.body.operations,\n );\n if (patched === originalContent) {\n return c.json({\n ok: true,\n changed: false,\n matched,\n content: originalContent,\n path: ctx.filePath,\n });\n }\n const backup = snapshotBeforeWrite(ctx.project.dir, ctx.absPath);\n if (backup.error) console.warn(`Failed to create backup for ${ctx.filePath}: ${backup.error}`);\n writeFileSync(ctx.absPath, patched, \"utf-8\");\n return c.json({\n ok: true,\n changed: true,\n matched,\n content: patched,\n path: ctx.filePath,\n backupPath: backupPathForResponse(ctx.project.dir, backup.backupPath),\n });\n });\n\n api.post(\"/projects/:id/file-mutations/probe-element/*\", async (c) => {\n const ctx = await resolveFileMutationContext(c, adapter, \"probe-element\");\n if (\"error\" in ctx) return ctx.error;\n\n const parsed = await parseMutationBody<{ target?: MutationTarget }>(c);\n if (\"error\" in parsed) return parsed.error;\n\n let content: string;\n try {\n content = readFileSync(ctx.absPath, \"utf-8\");\n } catch {\n return c.json({ exists: false });\n }\n\n const exists = probeElementInSource(content, parsed.target);\n return c.json({ exists });\n });\n\n // ── Rename / Move ──\n\n api.patch(\"/projects/:id/files/*\", async (c) => {\n const res = await resolveProjectFile(c, adapter, { mustExist: true });\n if (\"error\" in res) return res.error;\n\n const body = (await c.req.json()) as { newPath?: string };\n if (!body.newPath || body.newPath.includes(\"\\0\")) {\n return c.json({ error: \"newPath required\" }, 400);\n }\n\n const newAbs = resolveWithinProject(res.project.dir, body.newPath);\n if (!newAbs) {\n return c.json({ error: \"forbidden\" }, 403);\n }\n if (existsSync(newAbs)) {\n return c.json({ error: \"already exists\" }, 409);\n }\n\n ensureDir(newAbs);\n renameSync(res.absPath, newAbs);\n\n // Update references to the old path across all project files\n const updatedFiles = updateReferences(res.project.dir, res.filePath, body.newPath);\n\n return c.json({ ok: true, path: body.newPath, updatedReferences: updatedFiles });\n });\n\n // ── Duplicate ──\n\n api.post(\"/projects/:id/duplicate-file\", async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n\n const body = (await c.req.json()) as { path: string };\n if (!body.path || body.path.includes(\"\\0\")) {\n return c.json({ error: \"path required\" }, 400);\n }\n\n const srcAbs = resolveWithinProject(project.dir, body.path);\n if (!srcAbs || !existsSync(srcAbs)) {\n return c.json({ error: \"not found\" }, 404);\n }\n\n const copyPath = generateCopyPath(project.dir, body.path);\n const destAbs = resolveWithinProject(project.dir, copyPath);\n if (!destAbs) {\n return c.json({ error: \"forbidden\" }, 403);\n }\n\n ensureDir(destAbs);\n writeFileSync(destAbs, readFileSync(srcAbs));\n\n return c.json({ ok: true, path: copyPath }, 201);\n });\n\n // ── Upload (binary assets via multipart form) ──\n\n const MAX_UPLOAD_BYTES = 500 * 1024 * 1024; // 500 MB per file\n\n api.post(\n \"/projects/:id/upload\",\n bodyLimit({\n maxSize: MAX_UPLOAD_BYTES,\n onError: (c) => c.json({ error: \"payload too large\" }, 413),\n }),\n async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n\n // Optional subdirectory within the project (e.g. \"assets/audio\")\n const subDir = c.req.query(\"dir\") ?? \"\";\n const targetDir = subDir ? resolveWithinProject(project.dir, subDir) : project.dir;\n if (!targetDir) return c.json({ error: \"forbidden\" }, 403);\n if (subDir && !existsSync(targetDir)) mkdirSync(targetDir, { recursive: true });\n\n const formData = await c.req.formData();\n const result = await processUploadedFiles(formData, targetDir, project.dir);\n\n return c.json(\n { ok: true, files: result.uploaded, skipped: result.skipped, invalid: result.invalid },\n 201,\n );\n },\n );\n\n // ── GSAP Animations (parse) ──\n\n api.get(\"/projects/:id/gsap-animations/*\", async (c) => {\n const res = await resolveProjectPath(c, adapter, (id) => `/projects/${id}/gsap-animations/`, {\n mustExist: true,\n });\n if (\"error\" in res) return res.error;\n\n const html = readFileSync(res.absPath, \"utf-8\");\n const block = extractGsapScriptBlock(html);\n if (!block) {\n return c.json({\n animations: [],\n timelineVar: \"tl\",\n preamble: \"\",\n postamble: \"\",\n });\n }\n\n const parsed = parseGsapScriptAcorn(block.scriptText);\n return c.json(parsed);\n });\n\n // ── GSAP Mutations ──\n\n api.post(\"/projects/:id/gsap-mutations/*\", async (c) => {\n const res = await resolveProjectPath(c, adapter, (id) => `/projects/${id}/gsap-mutations/`, {\n mustExist: true,\n });\n if (\"error\" in res) return res.error;\n\n const body = (await c.req.json().catch(() => null)) as GsapMutationRequest | null;\n if (!body || !body.type) {\n return c.json({ error: \"mutation type required\" }, 400);\n }\n const unsafeFields = findUnsafeMutationValues(body);\n if (unsafeFields.length > 0) {\n return rejectUnsafeMutationValues(c, unsafeFields);\n }\n\n let html = readFileSync(res.absPath, \"utf-8\");\n let block = extractGsapScriptBlock(html);\n if (!block && (body.type === \"add\" || body.type === \"add-with-keyframes\")) {\n const compId = html.match(/data-composition-id=\"([^\"]+)\"/)?.[1] ?? \"main\";\n const { GSAP_CDN } = await import(\"@hyperframes/core\");\n const gsapCdn = `<script src=\"${GSAP_CDN}\"></script>`;\n const bootstrap = [\n gsapCdn,\n \"<script>\",\n \"window.__timelines = window.__timelines || {};\",\n `const tl = gsap.timeline({ paused: true });`,\n `window.__timelines[\"${compId}\"] = tl;`,\n \"</script>\",\n ].join(\"\\n\");\n if (html.includes(\"</body>\")) {\n html = html.replace(\"</body>\", `${bootstrap}\\n</body>`);\n } else {\n html += `\\n${bootstrap}`;\n }\n block = extractGsapScriptBlock(html);\n }\n if (!block) {\n return c.json({ error: \"no GSAP script found in file\" }, 400);\n }\n\n const respond = (data: unknown, status?: number) =>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- bridge between generic status and Hono's literal union\n status ? c.json(data, status as any) : c.json(data);\n\n const result = await executeGsapMutation(body, block, respond);\n if (result instanceof Response) return result;\n\n let newScript = typeof result === \"string\" ? result : result.script;\n // Keep the \"hold before first keyframe\" sets in sync after any mutation that can\n // change a position tween's first keyframe or its existence. Without it, an\n // element snaps to its CSS base before the tween starts instead of holding its\n // first keyframe (the universal NLE behavior).\n if (HOLD_SYNC_MUTATION_TYPES.has(body.type)) {\n const parser = await loadGsapParser();\n newScript = parser.syncPositionHoldsBeforeKeyframes(newScript);\n }\n const changed = newScript !== block.scriptText;\n const newHtml = changed ? block.replaceScript(newScript) : html;\n let backupPath: string | null = null;\n if (changed) {\n const backup = snapshotBeforeWrite(res.project.dir, res.absPath);\n if (backup.error)\n console.warn(`Failed to create backup for ${res.filePath}: ${backup.error}`);\n backupPath = backupPathForResponse(res.project.dir, backup.backupPath);\n writeFileSync(res.absPath, newHtml, \"utf-8\");\n }\n\n const freshParsed = parseGsapScriptAcorn(newScript);\n const responsePayload: Record<string, unknown> = {\n ok: true,\n changed,\n parsed: freshParsed,\n before: html,\n after: newHtml,\n scriptText: newScript,\n path: res.filePath,\n backupPath,\n };\n if (typeof result !== \"string\" && result.skippedSelectors.length > 0) {\n responsePayload.skippedSelectors = result.skippedSelectors;\n }\n return c.json(responsePayload);\n });\n}\n","export const MIME_TYPES: Record<string, string> = {\n \".html\": \"text/html\",\n \".css\": \"text/css\",\n \".js\": \"text/javascript\",\n \".mjs\": \"text/javascript\",\n \".json\": \"application/json\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".ico\": \"image/x-icon\",\n \".mp4\": \"video/mp4\",\n \".mov\": \"video/quicktime\",\n \".webm\": \"video/webm\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".ogg\": \"audio/ogg\",\n \".m4a\": \"audio/mp4\",\n \".aac\": \"audio/aac\",\n \".flac\": \"audio/flac\",\n \".opus\": \"audio/ogg\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".otf\": \"font/otf\",\n \".txt\": \"text/plain\",\n \".md\": \"text/markdown\",\n \".cube\": \"text/plain; charset=utf-8\",\n};\n\nexport function getMimeType(path: string): string {\n const ext = path.slice(path.lastIndexOf(\".\")).toLowerCase();\n return MIME_TYPES[ext] || \"application/octet-stream\";\n}\n\nexport function isAudioFile(name: string): boolean {\n return (getMimeType(name) ?? \"\").startsWith(\"audio/\");\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\n\nconst SAMPLE_RATE = 4000;\nconst PEAK_COUNT = 4000;\nconst WAVEFORM_CACHE_VERSION = \"v2\";\n\nexport function buildWaveformCacheKey(assetPath: string): string {\n return `${WAVEFORM_CACHE_VERSION}_${assetPath.replace(/[/\\\\]/g, \"_\")}.json`;\n}\n\nfunction computePeaks(floats: Float32Array, count: number): number[] {\n const step = floats.length / count;\n const peaks: number[] = [];\n for (let i = 0; i < count; i++) {\n const start = Math.floor(i * step);\n const end = Math.min(Math.floor((i + 1) * step), floats.length);\n let max = 0;\n for (let j = start; j < end; j++) {\n const abs = Math.abs(floats[j] ?? 0);\n if (abs > max) max = abs;\n }\n peaks.push(max);\n }\n const maxPeak = Math.max(...peaks, 0.001);\n return peaks.map((p) => p / maxPeak);\n}\n\nfunction ffmpegBinary(): string {\n const configured = process.env.HYPERFRAMES_FFMPEG_PATH?.trim();\n if (configured) return resolve(configured);\n return \"ffmpeg\";\n}\n\nexport function decodeAudioPeaks(audioPath: string): Promise<number[]> {\n return new Promise((resolvePromise, reject) => {\n const proc = spawn(\n ffmpegBinary(),\n [\n \"-i\",\n audioPath,\n \"-af\",\n \"atrim=start_sample=1152\",\n \"-f\",\n \"f32le\",\n \"-ac\",\n \"1\",\n \"-ar\",\n String(SAMPLE_RATE),\n \"-vn\",\n \"pipe:1\",\n ],\n { stdio: [\"ignore\", \"pipe\", \"ignore\"] },\n );\n\n const chunks: Buffer[] = [];\n proc.stdout?.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n proc.on(\"close\", (code) => {\n if (code !== 0 && chunks.length === 0) {\n reject(new Error(`ffmpeg exited with code ${code}`));\n return;\n }\n const buf = Buffer.concat(chunks);\n const numSamples = Math.floor(buf.length / 4);\n if (numSamples === 0) {\n reject(new Error(\"ffmpeg produced no audio samples\"));\n return;\n }\n const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + numSamples * 4);\n resolvePromise(computePeaks(new Float32Array(ab), PEAK_COUNT));\n });\n proc.on(\"error\", reject);\n });\n}\n\nexport async function generateWaveformCache(projectDir: string, assetPath: string): Promise<void> {\n const audioPath = join(projectDir, assetPath);\n if (!existsSync(audioPath)) return;\n\n const cacheDir = join(projectDir, \".waveform-cache\");\n const cachePath = join(cacheDir, buildWaveformCacheKey(assetPath));\n if (existsSync(cachePath)) return;\n\n const peaks = await decodeAudioPeaks(audioPath);\n mkdirSync(cacheDir, { recursive: true });\n writeFileSync(cachePath, JSON.stringify(peaks));\n}\n","import { spawnSync } from \"node:child_process\";\nimport { mkdtempSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { basename, join } from \"node:path\";\n\nconst VIDEO_EXT = /\\.(mp4|webm|mov)$/i;\nconst AUDIO_EXT = /\\.(mp3|wav|ogg|m4a|aac)$/i;\n\ntype FfprobeRunner = (\n command: string,\n args: string[],\n) => {\n status: number | null;\n stdout: string | Buffer;\n stderr: string | Buffer;\n error?: NodeJS.ErrnoException;\n};\n\nexport function validateUploadedMedia(\n filePath: string,\n runner: FfprobeRunner = spawnSync as unknown as FfprobeRunner,\n): { ok: true } | { ok: false; reason: string } {\n const isVideo = VIDEO_EXT.test(filePath);\n const isAudio = AUDIO_EXT.test(filePath);\n if (!isVideo && !isAudio) {\n return { ok: true };\n }\n\n const result = runner(\"ffprobe\", [\n \"-v\",\n \"error\",\n \"-show_entries\",\n \"stream=codec_type\",\n \"-of\",\n \"json\",\n filePath,\n ]);\n\n if (result.error?.code === \"ENOENT\") {\n return { ok: true };\n }\n if (result.status !== 0) {\n return { ok: false, reason: \"ffprobe failed to read the media file\" };\n }\n\n try {\n const parsed = JSON.parse(String(result.stdout || \"{}\")) as {\n streams?: Array<{ codec_type?: string }>;\n };\n const streams = parsed.streams ?? [];\n const hasVideo = streams.some((stream) => stream.codec_type === \"video\");\n const hasAudio = streams.some((stream) => stream.codec_type === \"audio\");\n\n if (isVideo && !hasVideo) {\n return { ok: false, reason: \"no supported video stream found\" };\n }\n if (isAudio && !hasAudio) {\n return { ok: false, reason: \"no supported audio stream found\" };\n }\n return { ok: true };\n } catch {\n return { ok: false, reason: \"ffprobe returned unreadable media metadata\" };\n }\n}\n\nexport function validateUploadedMediaBuffer(\n fileName: string,\n buffer: Uint8Array,\n runner: FfprobeRunner = spawnSync as unknown as FfprobeRunner,\n): { ok: true } | { ok: false; reason: string } {\n const tempDir = mkdtempSync(join(tmpdir(), \"hyperframes-upload-\"));\n const tempPath = join(tempDir, basename(fileName));\n\n try {\n writeFileSync(tempPath, buffer);\n return validateUploadedMedia(tempPath, runner);\n } finally {\n rmSync(tempDir, { recursive: true, force: true });\n }\n}\n","import { mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { Buffer } from \"node:buffer\";\nimport { join, relative } from \"node:path\";\nimport { isSafePath } from \"./safePath.js\";\n\nconst DEFAULT_KEEP_PER_FILE = 10;\n\nexport interface BackupJournalResult {\n backupPath: string | null;\n error?: string;\n}\n\nfunction backupKeyForPath(path: string): string {\n return Buffer.from(path, \"utf-8\").toString(\"base64url\");\n}\n\nfunction timestampPrefix(): string {\n return new Date().toISOString().replace(/[:.]/g, \"-\");\n}\n\nexport function backupPathForResponse(\n projectDir: string,\n backupPath: string | null,\n): string | null {\n if (!backupPath) return null;\n const rel = relative(projectDir, backupPath);\n if (!rel || rel.startsWith(\"..\")) return null;\n return rel.split(\"\\\\\").join(\"/\");\n}\n\nexport function snapshotBeforeWrite(\n projectDir: string,\n absPath: string,\n options: { keepPerFile?: number } = {},\n): BackupJournalResult {\n if (!isSafePath(projectDir, absPath)) return { backupPath: null };\n\n try {\n const content = readFileSync(absPath);\n\n const relativePath = relative(projectDir, absPath);\n const backupDir = join(projectDir, \".hyperframes\", \"backup\");\n mkdirSync(backupDir, { recursive: true });\n\n const backupKey = backupKeyForPath(relativePath);\n const backupPath = nextBackupPath(backupDir, backupKey);\n writeFileSync(backupPath, content);\n pruneBackups(backupDir, backupKey, options.keepPerFile ?? DEFAULT_KEEP_PER_FILE);\n return { backupPath };\n } catch (error) {\n if (\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n (error.code === \"ENOENT\" || error.code === \"EISDIR\")\n ) {\n return { backupPath: null };\n }\n return { backupPath: null, error: error instanceof Error ? error.message : String(error) };\n }\n}\n\nfunction nextBackupPath(backupDir: string, backupKey: string): string {\n const base = `${timestampPrefix()}-${backupKey}`;\n let candidate = join(backupDir, base);\n let counter = 2;\n while (true) {\n try {\n readFileSync(candidate);\n } catch (error) {\n if (error && typeof error === \"object\" && \"code\" in error && error.code === \"ENOENT\") {\n return candidate;\n }\n throw error;\n }\n candidate = join(backupDir, `${base}-${counter}`);\n counter += 1;\n }\n}\n\nfunction pruneBackups(backupDir: string, backupKey: string, keepPerFile: number): void {\n const keep = Math.max(1, Math.floor(keepPerFile));\n const suffix = `-${backupKey}`;\n const numberedSuffix = new RegExp(`-${backupKey}-\\\\d+$`);\n const matches = readdirSync(backupDir)\n .filter((name) => name.endsWith(suffix) || numberedSuffix.test(name))\n .map((name) => join(backupDir, name))\n .sort((a, b) => {\n return b.localeCompare(a);\n });\n\n for (const file of matches.slice(keep)) {\n try {\n unlinkSync(file);\n } catch {\n // Backup pruning is best-effort and must not block the user's write.\n }\n }\n}\n","export interface UnsafeMutationValue {\n path: string;\n reason: \"non-finite-number\" | \"null\";\n}\n\ninterface FindUnsafeMutationValuesOptions {\n allowNullPath?: (path: string) => boolean;\n}\n\nexport function findUnsafeMutationValues(\n value: unknown,\n path = \"body\",\n options: FindUnsafeMutationValuesOptions = {},\n): UnsafeMutationValue[] {\n if (value === null) {\n return options.allowNullPath?.(path) ? [] : [{ path, reason: \"null\" }];\n }\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? [] : [{ path, reason: \"non-finite-number\" }];\n }\n if (!value || typeof value !== \"object\") return [];\n if (Array.isArray(value)) {\n return value.flatMap((item, index) =>\n findUnsafeMutationValues(item, `${path}[${index}]`, options),\n );\n }\n return Object.entries(value).flatMap(([key, item]) =>\n findUnsafeMutationValues(item, `${path}.${key}`, options),\n );\n}\n\nconst DOM_PATCH_NULL_VALUE_PATH = /^body\\.operations\\[\\d+\\]\\.value$/;\n\nexport function findUnsafeDomPatchValues(value: unknown): UnsafeMutationValue[] {\n return findUnsafeMutationValues(value, \"body\", {\n allowNullPath: (path) => DOM_PATCH_NULL_VALUE_PATH.test(path),\n });\n}\n","import { parseHTML } from \"linkedom\";\nimport postcss from \"postcss\";\nimport selectorParser from \"postcss-selector-parser\";\nimport { isAllowedHtmlAttribute, isSafeAttributeValue } from \"@hyperframes/core/html-attr-safety\";\n\nexport interface SourceMutationTarget {\n id?: string | null;\n hfId?: string;\n selector?: string;\n selectorIndex?: number;\n}\n\nfunction parseSourceDocument(source: string): { document: Document; wrappedFragment: boolean } {\n const hasDocumentShell = /<!doctype|<html[\\s>]/i.test(source);\n if (hasDocumentShell) {\n return { document: parseHTML(source).document, wrappedFragment: false };\n }\n return {\n document: parseHTML(`<!DOCTYPE html><html><head></head><body>${source}</body></html>`).document,\n wrappedFragment: true,\n };\n}\n\nfunction duplicateCssRulesForId(document: Document, originalId: string, newId: string): void {\n const idToken = `#${originalId}`;\n const transform = selectorParser((selectors) => {\n selectors.walkIds((node) => {\n if (node.value === originalId) node.value = newId;\n });\n });\n for (const styleEl of document.querySelectorAll(\"style\")) {\n const css = styleEl.textContent ?? \"\";\n let root: postcss.Root;\n try {\n root = postcss.parse(css);\n } catch {\n continue;\n }\n const clones: postcss.Rule[] = [];\n root.walkRules((rule) => {\n if (!rule.selector.includes(idToken)) return;\n const newSelector = transform.processSync(rule.selector);\n if (newSelector === rule.selector) return;\n const clone = rule.clone({ selector: newSelector });\n clones.push(clone);\n });\n if (clones.length > 0) {\n for (const c of clones) root.append(c);\n styleEl.textContent = root.toString();\n }\n }\n}\n\nfunction querySelectorAllWithTemplates(root: Document | Element, selector: string): Element[] {\n const matches = Array.from(root.querySelectorAll(selector));\n if (matches.length > 0) return matches;\n // querySelectorAll doesn't traverse <template> content in linkedom.\n // Search directly on each template element (NOT .content — removing from\n // .content's DocumentFragment doesn't update the serialized output).\n const templates = Array.from(root.querySelectorAll(\"template\"));\n for (const tmpl of templates) {\n const inner = tmpl.querySelectorAll(selector);\n if (inner.length > 0) return Array.from(inner);\n }\n return [];\n}\n\n// Prevent CSS attribute-selector injection via a crafted hfId: escape\n// backslashes first, then double-quotes. Keeps a malformed/hostile value from\n// breaking out of the `[data-hf-id=\"…\"]` selector once callers beyond the\n// internal mint contract (R2+ user flows) pass values here.\nfunction escapeCssAttrValue(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction findByHfId(document: Document, hfId: string): Element | null {\n try {\n const matches = querySelectorAllWithTemplates(\n document,\n `[data-hf-id=\"${escapeCssAttrValue(hfId)}\"]`,\n );\n if (matches.length > 1) {\n // The mint contract guarantees uniqueness; a duplicate means upstream\n // id drift. Don't silently patch an arbitrary one — surface it.\n // eslint-disable-next-line no-console\n console.warn(\n `sourceMutation: data-hf-id \"${hfId}\" matched ${matches.length} elements; using the first. ids must be unique per document.`,\n );\n }\n return matches[0] ?? null;\n } catch {\n // Malformed selector despite escaping — let the caller fall back.\n return null;\n }\n}\n\nfunction findTargetElement(document: Document, target: SourceMutationTarget): Element | null {\n if (target.hfId) {\n const el = findByHfId(document, target.hfId);\n if (el) return el;\n }\n\n if (target.id) {\n const byId = document.getElementById(target.id);\n if (byId) return byId;\n }\n\n if (!target.selector) return null;\n try {\n const matches = querySelectorAllWithTemplates(document, target.selector);\n return matches[target.selectorIndex ?? 0] ?? null;\n } catch {\n return null;\n }\n}\n\nexport function removeElementFromHtml(source: string, target: SourceMutationTarget): string {\n const { document, wrappedFragment } = parseSourceDocument(source);\n const element = findTargetElement(document, target);\n if (!element) return source;\n\n element.remove();\n return wrappedFragment ? document.body.innerHTML || \"\" : document.toString();\n}\n\nexport function isHTMLElement(el: Element): el is HTMLElement {\n const HTMLEl = el.ownerDocument.defaultView?.HTMLElement;\n return HTMLEl ? el instanceof HTMLEl : \"style\" in el;\n}\n\nexport interface PatchOperation {\n type: \"inline-style\" | \"attribute\" | \"html-attribute\" | \"text-content\";\n property: string;\n value: string | null;\n}\n\n// fallow-ignore-next-line complexity\nfunction patchStyleAttrString(style: string, property: string, value: string | null): string {\n const props = new Map<string, string>();\n const order: string[] = [];\n // Tokenize declarations robustly: values can contain ';' inside quoted strings\n // (e.g. content: ';') and ':' inside values (data URIs, url(), etc.).\n // Split on ';' only when outside quotes and balanced parens; the first ':' in\n // the resulting segment is the property/value separator (property names never\n // contain ':').\n let i = 0;\n while (i < style.length) {\n let depth = 0;\n let inSingle = false;\n let inDouble = false;\n const start = i;\n while (i < style.length) {\n const ch = style[i];\n if (ch === \"'\" && !inDouble) inSingle = !inSingle;\n else if (ch === '\"' && !inSingle) inDouble = !inDouble;\n else if (!inSingle && !inDouble) {\n if (ch === \"(\") depth++;\n else if (ch === \")\") depth = Math.max(0, depth - 1);\n else if (ch === \";\" && depth === 0) break;\n }\n i++;\n }\n const decl = style.slice(start, i).trim();\n i++; // advance past ';'\n if (!decl) continue;\n const colon = decl.indexOf(\":\");\n if (colon < 0) continue;\n const key = decl.slice(0, colon).trim();\n const val = decl.slice(colon + 1).trim();\n if (!key) continue;\n if (!props.has(key)) order.push(key);\n props.set(key, val);\n }\n if (value === null) {\n props.delete(property);\n const idx = order.indexOf(property);\n if (idx >= 0) order.splice(idx, 1);\n } else {\n if (!props.has(property)) order.push(property);\n props.set(property, value);\n }\n return order\n .map((k) => `${k}: ${props.get(k) ?? \"\"}`)\n .filter((d) => d.trim())\n .join(\"; \");\n}\n\n// fallow-ignore-next-line complexity\nexport function patchElementInHtml(\n source: string,\n target: SourceMutationTarget,\n operations: PatchOperation[],\n): { html: string; matched: boolean } {\n const { document, wrappedFragment } = parseSourceDocument(source);\n const el = findTargetElement(document, target);\n if (!el || !isHTMLElement(el)) return { html: source, matched: false };\n const htmlEl = el;\n\n for (const op of operations) {\n switch (op.type) {\n case \"inline-style\":\n // linkedom's CSSStyleDeclaration does not support CSS custom properties\n // (--foo) or newer individual transform properties (translate, rotate,\n // scale) via style.setProperty(). Manipulate the style attribute string\n // directly so all property names survive the round-trip.\n {\n const raw = htmlEl.getAttribute(\"style\") ?? \"\";\n const patched = patchStyleAttrString(raw, op.property, op.value);\n htmlEl.setAttribute(\"style\", patched);\n }\n break;\n case \"attribute\":\n {\n const fullAttr = op.property.startsWith(\"data-\") ? op.property : `data-${op.property}`;\n if (op.value != null) {\n htmlEl.setAttribute(fullAttr, op.value);\n } else {\n htmlEl.removeAttribute(fullAttr);\n }\n }\n break;\n case \"html-attribute\":\n if (!isAllowedHtmlAttribute(op.property)) break;\n if (op.value != null) {\n if (!isSafeAttributeValue(op.property, op.value)) break;\n htmlEl.setAttribute(op.property, op.value);\n } else {\n htmlEl.removeAttribute(op.property);\n }\n break;\n case \"text-content\":\n if (op.value != null) {\n const inner = htmlEl.children.length === 1 ? htmlEl.firstElementChild : null;\n const textTarget = inner && isHTMLElement(inner) ? inner : htmlEl;\n textTarget.textContent = op.value;\n }\n break;\n }\n }\n\n return {\n html: wrappedFragment ? document.body.innerHTML || \"\" : document.toString(),\n matched: true,\n };\n}\n\nexport function probeElementInSource(source: string, target: SourceMutationTarget): boolean {\n if (!target.id && !target.hfId && !target.selector) return false;\n const { document } = parseSourceDocument(source);\n const el = findTargetElement(document, target);\n return el != null && isHTMLElement(el);\n}\n\nexport interface SplitElementResult {\n html: string;\n matched: boolean;\n newId: string | null;\n}\n\nfunction resolveElementTiming(el: Element): {\n start: number;\n duration: number;\n usesDataEnd: boolean;\n} {\n const start = parseFloat(el.getAttribute(\"data-start\") ?? \"0\") || 0;\n const usesDataEnd = el.hasAttribute(\"data-end\");\n const duration = usesDataEnd\n ? parseFloat(el.getAttribute(\"data-end\") ?? \"\") - start || 0\n : parseFloat(el.getAttribute(\"data-duration\") ?? \"0\") || 0;\n return { start, duration, usesDataEnd };\n}\n\nfunction setElementDuration(\n el: Element,\n start: number,\n duration: number,\n usesDataEnd: boolean,\n): void {\n if (usesDataEnd) {\n const endTime = String(Math.round((start + duration) * 1000) / 1000);\n el.setAttribute(\"data-end\", endTime);\n el.removeAttribute(\"data-duration\");\n } else {\n el.setAttribute(\"data-duration\", String(Math.round(duration * 1000) / 1000));\n el.removeAttribute(\"data-end\");\n }\n}\n\n// fallow-ignore-next-line complexity\nexport function splitElementInHtml(\n source: string,\n target: SourceMutationTarget,\n splitTime: number,\n newId: string,\n fallbackTiming?: { start: number; duration: number },\n): SplitElementResult {\n const { document, wrappedFragment } = parseSourceDocument(source);\n const el = findTargetElement(document, target);\n if (!el || !isHTMLElement(el)) return { html: source, matched: false, newId: null };\n\n const timing = resolveElementTiming(el);\n const { usesDataEnd } = timing;\n let { start, duration } = timing;\n // GSAP-animated elements carry their timing in the script, not in data-* attrs,\n // so the source has no authored duration. Fall back to the store's (GSAP-derived)\n // range — the runtime windows visibility off data-start/data-duration regardless\n // of class, so stamping both halves below makes each half show only in its window.\n if (duration <= 0 && fallbackTiming && fallbackTiming.duration > 0) {\n start = fallbackTiming.start;\n duration = fallbackTiming.duration;\n }\n if (duration <= 0 || splitTime <= start || splitTime >= start + duration) {\n return { html: source, matched: false, newId: null };\n }\n\n if (document.getElementById(newId)) {\n let suffix = 2;\n const base = newId;\n while (document.getElementById(newId)) {\n newId = `${base}-${suffix++}`;\n }\n }\n\n const firstDuration = splitTime - start;\n const secondDuration = duration - firstDuration;\n\n const clone = el.cloneNode(true) as HTMLElement;\n clone.setAttribute(\"id\", newId);\n clone.removeAttribute(\"data-hf-id\");\n // Descendants carry their own data-hf-id; leaving them duplicates the id of\n // every nested node (e.g. an inner <span>), so strip them on the clone too.\n for (const node of clone.querySelectorAll(\"[data-hf-id]\")) node.removeAttribute(\"data-hf-id\");\n clone.setAttribute(\"data-start\", String(Math.round(splitTime * 1000) / 1000));\n setElementDuration(clone, splitTime, secondDuration, usesDataEnd);\n\n // Keep the \"clip\" class — the runtime uses it to control visibility\n // based on data-start/data-duration timing.\n\n // Adjust media trim offset for the second half\n const playbackStartAttr = el.hasAttribute(\"data-playback-start\")\n ? \"data-playback-start\"\n : el.hasAttribute(\"data-media-start\")\n ? \"data-media-start\"\n : null;\n if (playbackStartAttr) {\n const currentTrim = parseFloat(el.getAttribute(playbackStartAttr) ?? \"0\") || 0;\n const rateRaw = parseFloat(el.getAttribute(\"data-playback-rate\") ?? \"\");\n const rate = Number.isFinite(rateRaw) ? rateRaw : 1;\n clone.setAttribute(\n playbackStartAttr,\n String(Math.round((currentTrim + firstDuration * rate) * 1000) / 1000),\n );\n }\n\n // Duplicate CSS rules targeting the original ID so the clone inherits the same styles.\n const originalId = el.getAttribute(\"id\");\n if (originalId) {\n duplicateCssRulesForId(document, originalId, newId);\n }\n\n // Trim the original element's duration. A GSAP element had no data-start; stamp\n // it so the runtime windows the first half (visibility selects on [data-start]).\n el.setAttribute(\"data-start\", String(Math.round(start * 1000) / 1000));\n setElementDuration(el, start, firstDuration, usesDataEnd);\n\n // Insert clone after original\n if (el.nextSibling) {\n el.parentElement!.insertBefore(clone, el.nextSibling);\n } else {\n el.parentElement!.appendChild(clone);\n }\n\n return {\n html: wrappedFragment ? document.body.innerHTML || \"\" : document.toString(),\n matched: true,\n newId,\n };\n}\n","import type { Hono } from \"hono\";\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { injectScriptsIntoHtml, stripEmbeddedRuntimeScripts } from \"@hyperframes/core/compiler\";\nimport type { StudioApiAdapter } from \"../types.js\";\nimport { resolveWithinProject } from \"../helpers/safePath.js\";\nimport { getMimeType } from \"../helpers/mime.js\";\nimport { buildSubCompositionHtml } from \"../helpers/subComposition.js\";\nimport { createProjectSignature } from \"../helpers/projectSignature.js\";\nimport {\n createStudioMotionRenderBodyScript,\n STUDIO_MOTION_PATH,\n} from \"../helpers/studioMotionRenderScript.js\";\nimport { ensureHfIds } from \"@hyperframes/parsers/hf-ids\";\nimport { persistHfIdsIfNeeded } from \"../helpers/hfIdPersist.js\";\n\nconst PROJECT_SIGNATURE_META = \"hyperframes-project-signature\";\nconst GSAP_CDN_VERSION = \"3.15.0\";\nconst GSAP_CDN_SCRIPT = `<script src=\"https://cdn.jsdelivr.net/npm/gsap@${GSAP_CDN_VERSION}/dist/gsap.min.js\"></script>`;\nconst GSAP_CUSTOM_EASE_CDN_SCRIPT = `<script src=\"https://cdn.jsdelivr.net/npm/gsap@${GSAP_CDN_VERSION}/dist/CustomEase.min.js\"></script>`;\nconst GSAP_MOTION_PATH_CDN_SCRIPT = `<script src=\"https://cdn.jsdelivr.net/npm/gsap@${GSAP_CDN_VERSION}/dist/MotionPathPlugin.min.js\"></script>`;\n\nfunction resolveProjectSignature(adapter: StudioApiAdapter, projectDir: string): string {\n return adapter.getProjectSignature?.(projectDir) ?? createProjectSignature(projectDir);\n}\n\nfunction injectProjectSignature(html: string, signature: string): string {\n const tag = `<meta name=\"${PROJECT_SIGNATURE_META}\" content=\"${signature}\">`;\n if (html.includes(`name=\"${PROJECT_SIGNATURE_META}\"`)) {\n return html.replace(\n new RegExp(`<meta\\\\s+name=[\"']${PROJECT_SIGNATURE_META}[\"'][^>]*>`, \"i\"),\n tag,\n );\n }\n if (html.includes(\"</head>\")) return html.replace(\"</head>\", `${tag}\\n</head>`);\n return `${tag}\\n${html}`;\n}\n\nfunction readStudioMotionManifestContent(projectDir: string): string {\n const manifestPath = join(projectDir, STUDIO_MOTION_PATH);\n if (!existsSync(manifestPath)) return \"\";\n try {\n return readFileSync(manifestPath, \"utf-8\");\n } catch {\n return \"\";\n }\n}\n\nfunction parseStudioMotionManifestContent(content: string): {\n hasMotion: boolean;\n hasCustomEase: boolean;\n} {\n try {\n const parsed = JSON.parse(content) as { motions?: Array<{ customEase?: unknown }> };\n const motions = Array.isArray(parsed.motions) ? parsed.motions : [];\n return {\n hasMotion: motions.length > 0,\n hasCustomEase: motions.some((motion) => Boolean(motion?.customEase)),\n };\n } catch {\n return { hasMotion: false, hasCustomEase: false };\n }\n}\n\nfunction injectScriptTagIntoHead(html: string, scriptTag: string): string {\n if (html.includes(\"</head>\")) return html.replace(\"</head>\", `${scriptTag}\\n</head>`);\n return `${scriptTag}\\n${html}`;\n}\n\nfunction htmlHasGsap(html: string): boolean {\n // Only match GSAP references outside <template> elements — scripts inside\n // templates are inert when cloned and don't make GSAP globally available.\n const outsideTemplates = html.replace(/<template\\b[^>]*>[\\s\\S]*?<\\/template>/gi, \"\");\n return (\n /<script\\b[^>]*src=[\"'][^\"']*gsap/i.test(outsideTemplates) ||\n /\\/\\*\\s*inlined:.*gsap/i.test(outsideTemplates) ||\n /\\b(GreenSock|_gsScope)\\b/.test(outsideTemplates) ||\n /\\bgsap\\.(config|defaults|registerPlugin|version)\\b/.test(outsideTemplates)\n );\n}\n\nfunction htmlHasCustomEase(html: string): boolean {\n return (\n /<script\\b[^>]*src=[\"'][^\"']*CustomEase/i.test(html) ||\n /\\bwindow\\.CustomEase\\b/.test(html) ||\n /\\bCustomEase\\s*=\\s*/.test(html)\n );\n}\n\n// A composition that drives motion via GSAP's `motionPath` (e.g. a studio-created\n// motion path written into the single-source timeline) needs MotionPathPlugin\n// registered before the timeline first renders — otherwise the initial seek\n// throws \"Invalid property motionPath ... Missing plugin?\". Detect it anywhere in\n// the bundle (the plugin registers globally, so sub-composition usage counts too).\nfunction htmlUsesMotionPath(html: string): boolean {\n return /motionPath\\s*[:{]/.test(html);\n}\n\nfunction htmlHasMotionPathPlugin(html: string): boolean {\n return (\n /<script\\b[^>]*src=[\"'][^\"']*MotionPathPlugin/i.test(html) ||\n /\\bwindow\\.MotionPathPlugin\\b/.test(html) ||\n /\\bMotionPathPlugin\\s*=\\s*/.test(html)\n );\n}\n\nfunction injectMotionPathPluginIfNeeded(html: string): string {\n if (!htmlUsesMotionPath(html) || htmlHasMotionPathPlugin(html)) return html;\n // The plugin registers onto an already-loaded gsap, so it must come AFTER the\n // core gsap script — which often lives at body-end, not <head>. Insert it\n // directly after the gsap script tag; only fall back to <head> if none is found\n // (e.g. gsap is inlined).\n const gsapScript = /<script\\b[^>]*\\bsrc=[\"'][^\"']*\\/gsap(\\.min)?\\.js[\"'][^>]*>\\s*<\\/script>/i;\n const match = html.match(gsapScript);\n if (match) {\n // Match the plugin version to the composition's own gsap so the plugin\n // registers cleanly (a minor-version skew triggers a GSAP compatibility warning).\n const version = match[0].match(/gsap@([\\d.]+)/)?.[1] ?? GSAP_CDN_VERSION;\n const pluginTag = `<script src=\"https://cdn.jsdelivr.net/npm/gsap@${version}/dist/MotionPathPlugin.min.js\"></script>`;\n const end = html.indexOf(match[0]) + match[0].length;\n return html.slice(0, end) + \"\\n\" + pluginTag + html.slice(end);\n }\n return injectScriptTagIntoHead(html, GSAP_MOTION_PATH_CDN_SCRIPT);\n}\n\nfunction injectStudioMotionDependencies(html: string, manifestContent: string): string {\n const manifest = parseStudioMotionManifestContent(manifestContent);\n if (!manifest.hasMotion) return html;\n let next = html;\n if (!htmlHasGsap(next)) next = injectScriptTagIntoHead(next, GSAP_CDN_SCRIPT);\n if (manifest.hasCustomEase && !htmlHasCustomEase(next)) {\n next = injectScriptTagIntoHead(next, GSAP_CUSTOM_EASE_CDN_SCRIPT);\n }\n return next;\n}\n\nfunction injectStudioMotionScript(\n html: string,\n projectDir: string,\n activeCompositionPath: string,\n): string {\n const manifestContent = readStudioMotionManifestContent(projectDir);\n const script = createStudioMotionRenderBodyScript(manifestContent, {\n activeCompositionPath,\n });\n if (!script) return html;\n return injectScriptsIntoHtml(\n injectStudioMotionDependencies(html, manifestContent),\n [],\n [script],\n false,\n );\n}\n\nconst GSAP_CDN_FALLBACK_SCRIPT = `<script data-hf-gsap-fallback>\n(function(){\n var cdnBase=\"https://cdn.jsdelivr.net/npm/gsap@${GSAP_CDN_VERSION}/dist/\";\n var loaded={};\n function loadFallback(file){\n if(loaded[file])return loaded[file];\n return loaded[file]=new Promise(function(ok,fail){\n var s=document.createElement(\"script\");\n s.src=cdnBase+file;s.onload=ok;s.onerror=fail;\n document.head.appendChild(s);\n });\n }\n document.addEventListener(\"error\",function(e){\n var t=e.target;\n if(!t||t.tagName!==\"SCRIPT\"||!t.src)return;\n var m=t.src.match(/gsap[^/]*\\\\/dist\\\\/(.+\\\\.js)/);\n if(m)loadFallback(m[1]);\n },true);\n})();\n</script>`;\n\nfunction injectGsapCdnFallback(html: string): string {\n if (html.includes(\"data-hf-gsap-fallback\")) return html;\n if (html.includes(\"<head>\")) return html.replace(\"<head>\", \"<head>\" + GSAP_CDN_FALLBACK_SCRIPT);\n return GSAP_CDN_FALLBACK_SCRIPT + html;\n}\n\nfunction injectStudioPreviewAugmentations(\n html: string,\n adapter: StudioApiAdapter,\n projectDir: string,\n activeCompositionPath: string,\n): string {\n return injectStudioMotionScript(\n injectMotionPathPluginIfNeeded(\n injectGsapCdnFallback(\n injectProjectSignature(html, resolveProjectSignature(adapter, projectDir)),\n ),\n ),\n projectDir,\n activeCompositionPath,\n );\n}\n\nasync function transformPreviewHtml(\n html: string,\n adapter: StudioApiAdapter,\n project: { id: string; dir: string; title?: string; sessionId?: string },\n activeCompositionPath: string,\n): Promise<string> {\n if (!adapter.transformPreviewHtml) return html;\n try {\n return await adapter.transformPreviewHtml({\n html,\n project,\n activeCompositionPath,\n });\n } catch (err) {\n console.warn(\"[Studio] preview transform failed, using original HTML:\", err);\n return html;\n }\n}\n\nfunction resolveProjectMainHtml(\n projectDir: string,\n projectId: string,\n): { html: string; compositionPath: string } | null {\n const indexPath = join(projectDir, \"index.html\");\n if (existsSync(indexPath)) {\n return { html: readFileSync(indexPath, \"utf-8\"), compositionPath: \"index.html\" };\n }\n const blockHtmlPath = join(projectDir, `${projectId}.html`);\n if (existsSync(blockHtmlPath)) {\n return { html: readFileSync(blockHtmlPath, \"utf-8\"), compositionPath: `${projectId}.html` };\n }\n return null;\n}\n\nexport function registerPreviewRoutes(api: Hono, adapter: StudioApiAdapter): void {\n const previewCacheHeaders = (etag: string) => ({\n \"Cache-Control\": \"private, no-cache\",\n ETag: etag,\n });\n\n // Bundled composition preview\n // fallow-ignore-next-line complexity\n api.get(\"/projects/:id/preview\", async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n\n const signature = resolveProjectSignature(adapter, project.dir);\n const etag = `\"preview:${signature}\"`;\n const ifNoneMatch = c.req.header(\"If-None-Match\");\n if (ifNoneMatch === etag) {\n return new Response(null, { status: 304, headers: previewCacheHeaders(etag) });\n }\n\n // Normalize + persist data-hf-id to disk before bundle reads it. Idempotent.\n const diskMain = resolveProjectMainHtml(project.dir, project.id);\n const normalizedDisk = diskMain\n ? persistHfIdsIfNeeded(join(project.dir, diskMain.compositionPath), diskMain.html)\n : null;\n\n try {\n let bundled = await adapter.bundle(project.dir);\n let mainCompositionPath = \"index.html\";\n if (!bundled) {\n if (!diskMain) return c.text(\"not found\", 404);\n // Disk HTML may carry a baked inline runtime from a prior export; strip\n // it so the preview runtime injected below isn't double-loaded (the\n // bundled path already strips via htmlBundler). Idempotent if absent.\n bundled = stripEmbeddedRuntimeScripts(normalizedDisk ?? diskMain.html);\n mainCompositionPath = diskMain.compositionPath;\n }\n\n // Inject runtime if not already present (check URL pattern and bundler attribute)\n if (\n !bundled.includes(\"hyperframe.runtime\") &&\n !bundled.includes(\"hyperframes-preview-runtime\")\n ) {\n const runtimeTag = `<script src=\"${adapter.runtimeUrl}\"></script>`;\n bundled = bundled.includes(\"</body>\")\n ? bundled.replace(\"</body>\", `${runtimeTag}\\n</body>`)\n : bundled + `\\n${runtimeTag}`;\n }\n\n // Inject <base> for relative asset resolution\n const baseHref = `/api/projects/${project.id}/preview/`;\n if (!bundled.includes(\"<base\")) {\n bundled = bundled.replace(/<head>/i, `<head><base href=\"${baseHref}\">`);\n }\n\n // ensureHfIds runs after transformPreviewHtml in case the adapter injected\n // new elements. On the no-bundle path bundled=normalizedDisk (already tagged)\n // so this is idempotent. On the bundled path the bundler may return untagged\n // HTML (stale cache); because ids are content-keyed the minted ids will match\n // the ids already written to disk by persistHfIdsIfNeeded above.\n bundled = injectStudioPreviewAugmentations(\n ensureHfIds(await transformPreviewHtml(bundled, adapter, project, mainCompositionPath)),\n adapter,\n project.dir,\n mainCompositionPath,\n );\n return c.html(bundled, 200, previewCacheHeaders(etag));\n } catch {\n // Re-read disk on bundle failure so we serve the latest file content,\n // not the pre-request snapshot that may have been saved over.\n const fallback = resolveProjectMainHtml(project.dir, project.id);\n if (fallback) {\n const fallbackHtml = persistHfIdsIfNeeded(\n join(project.dir, fallback.compositionPath),\n fallback.html,\n );\n return c.html(\n injectStudioPreviewAugmentations(\n await transformPreviewHtml(fallbackHtml, adapter, project, fallback.compositionPath),\n adapter,\n project.dir,\n fallback.compositionPath,\n ),\n 200,\n previewCacheHeaders(etag),\n );\n }\n return c.text(\"not found\", 404);\n }\n });\n\n // Sub-composition preview\n api.get(\"/projects/:id/preview/comp/*\", async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n\n const signature = resolveProjectSignature(adapter, project.dir);\n const compPath = decodeURIComponent(\n c.req.path.replace(`/projects/${project.id}/preview/comp/`, \"\").split(\"?\")[0] ?? \"\",\n );\n const compFile = resolveWithinProject(project.dir, compPath);\n if (!compFile || !existsSync(compFile) || !statSync(compFile).isFile()) {\n return c.text(\"not found\", 404);\n }\n\n const etag = `\"comp:${compPath}:${signature}\"`;\n const ifNoneMatch = c.req.header(\"If-None-Match\");\n if (ifNoneMatch === etag) {\n return new Response(null, { status: 304, headers: previewCacheHeaders(etag) });\n }\n\n const baseHref = `/api/projects/${project.id}/preview/`;\n let html = buildSubCompositionHtml(project.dir, compPath, adapter.runtimeUrl, baseHref);\n if (!html) return c.text(\"not found\", 404);\n html = ensureHfIds(await transformPreviewHtml(html, adapter, project, compPath));\n return c.html(\n injectStudioPreviewAugmentations(html, adapter, project.dir, compPath),\n 200,\n previewCacheHeaders(etag),\n );\n });\n\n // Static asset serving (with range request support for audio/video seeking)\n // fallow-ignore-next-line complexity\n api.get(\"/projects/:id/preview/*\", async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n const subPath = decodeURIComponent(\n c.req.path.replace(`/projects/${project.id}/preview/`, \"\").split(\"?\")[0] ?? \"\",\n );\n const file = resolveWithinProject(project.dir, subPath);\n if (!file) {\n return c.text(\"not found\", 404);\n }\n const stat = existsSync(file) ? statSync(file) : null;\n if (!stat?.isFile()) {\n return c.text(\"not found\", 404);\n }\n const contentType = getMimeType(subPath);\n const isText = /\\.(html|css|js|json|svg|txt|md|cube)$/i.test(subPath);\n\n const etag = `\"${stat.mtimeMs.toString(36)}-${stat.size.toString(36)}\"`;\n const cacheHeaders: Record<string, string> = isText\n ? { \"Cache-Control\": \"no-store\" }\n : { \"Cache-Control\": \"private, max-age=3600, must-revalidate\", ETag: etag };\n\n if (!isText) {\n const ifNoneMatch = c.req.header(\"If-None-Match\");\n if (ifNoneMatch === etag) {\n return new Response(null, { status: 304, headers: cacheHeaders });\n }\n }\n\n const buffer: Buffer = isText\n ? Buffer.from(readFileSync(file, \"utf-8\"), \"utf-8\")\n : readFileSync(file);\n const totalSize = buffer.length;\n\n // Support byte-range requests so browsers can seek audio/video elements.\n const rangeHeader = c.req.header(\"Range\");\n if (rangeHeader) {\n const match = /bytes=(\\d+)-(\\d*)/.exec(rangeHeader);\n if (match) {\n const start = parseInt(match[1]!, 10);\n const end = match[2] ? parseInt(match[2], 10) : totalSize - 1;\n const safeEnd = Math.min(end, totalSize - 1);\n const chunkSize = safeEnd - start + 1;\n return new Response(new Uint8Array(buffer.slice(start, safeEnd + 1)), {\n status: 206,\n headers: {\n ...cacheHeaders,\n \"Content-Type\": contentType,\n \"Content-Range\": `bytes ${start}-${safeEnd}/${totalSize}`,\n \"Accept-Ranges\": \"bytes\",\n \"Content-Length\": String(chunkSize),\n },\n });\n }\n }\n\n return new Response(new Uint8Array(buffer), {\n headers: {\n ...cacheHeaders,\n \"Content-Type\": contentType,\n \"Accept-Ranges\": \"bytes\",\n \"Content-Length\": String(totalSize),\n },\n });\n });\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { parseHTML } from \"linkedom\";\nimport {\n rewriteAssetPaths,\n rewriteCssAssetUrls,\n rewriteInlineStyleAssetUrls,\n} from \"@hyperframes/core\";\nimport { stripEmbeddedRuntimeScripts } from \"@hyperframes/core/compiler\";\n\n/**\n * Detect whether `html` is a full document (has `<html>`, `<head>`, or\n * `<!doctype`), as opposed to a `<template>`-wrapped fragment.\n * Anchored to start-of-string (ignoring leading whitespace) so stray\n * occurrences inside script/template content don't false-positive.\n */\nfunction isFullHtmlDocument(html: string): boolean {\n return /^\\s*(?:<!doctype\\s|<html[\\s>])/i.test(html);\n}\n\n/**\n * Rewrite relative asset paths in a parsed DOM tree. Shared across all\n * three dispatch branches (template, full-doc, fragment) to avoid drift.\n */\nfunction rewriteRelativePaths(root: ParentNode, compPath: string): void {\n rewriteAssetPaths(\n root.querySelectorAll(\"[src], [href]\"),\n compPath,\n (el: Element, attr: string) => el.getAttribute(attr),\n (el: Element, attr: string, value: string) => el.setAttribute(attr, value),\n );\n rewriteInlineStyleAssetUrls(\n root.querySelectorAll(\"[style]\"),\n compPath,\n (el: Element) => el.getAttribute(\"style\"),\n (el: Element, value: string) => el.setAttribute(\"style\", value),\n );\n for (const styleEl of root.querySelectorAll(\"style\")) {\n styleEl.textContent = rewriteCssAssetUrls(styleEl.textContent || \"\", compPath);\n }\n}\n\n/**\n * Escape a CSS identifier whose first character is a digit so it is a valid\n * selector. A CSS ident cannot start with a digit, so it must be written as an\n * escaped code point: `01-foo` → `\\30 1-foo` (leading `0` → `\\30 `, rest kept).\n *\n * Only the leading digit needs escaping (per CSS Syntax Level 3 §4.3.11): once\n * the parser consumes the `\\<hex> ` escape, the rest of the ident continues\n * normally, so `123-scene` → `\\31 23-scene` is valid (the `23-scene` tail is\n * consumed as identifier continuation). The trailing space terminates the hex\n * escape so a following hex digit isn't folded into the code point.\n */\nfunction escapeLeadingDigitIdent(id: string): string {\n return `\\\\${id.charCodeAt(0).toString(16)} ${id.slice(1)}`;\n}\n\nconst REGEXP_SPECIALS = /[.*+?^${}()|[\\]\\\\]/g;\n\n/**\n * Fix `#<digit-leading-id>` selectors in the tree's `<style>` blocks.\n *\n * CSS identifiers cannot start with a digit, so an authored rule like\n * `#01-wall-pushes-back { width: 1920px; height: 1080px; background: #F0EBDE }`\n * is an invalid selector and the browser silently drops the WHOLE rule — taking\n * the root's size and background with it. In a full composition the frame is\n * stretched/painted by its `data-composition-src` host so the collapse is\n * masked, but a standalone preview has no host: the root falls back to\n * `height: 0` + transparent and the frame renders blank (black).\n *\n * Rewrite each such selector to its escaped, valid form (`#\\30 1-wall-pushes-back`,\n * which still matches `id=\"01-wall-pushes-back\"`) so the rule applies and the\n * whole declaration block — size, background, position, container-type — comes\n * back. Scoped to ids that are actually present on elements in the content and\n * matched only as `#id` not followed by another ident char, so hex colors\n * (`#1F2BE0`) and other values are never touched (they are not element ids).\n */\nfunction fixDigitLeadingIdSelectors(root: ParentNode): void {\n const digitIds = new Set<string>();\n for (const el of root.querySelectorAll(\"[id]\")) {\n const id = el.getAttribute(\"id\");\n if (id && /^\\d/.test(id)) digitIds.add(id);\n }\n if (digitIds.size === 0) return;\n\n for (const styleEl of root.querySelectorAll(\"style\")) {\n let css = styleEl.textContent || \"\";\n for (const id of digitIds) {\n const pattern = new RegExp(`#${id.replace(REGEXP_SPECIALS, \"\\\\$&\")}(?![\\\\w-])`, \"g\");\n css = css.replace(pattern, `#${escapeLeadingDigitIdent(id)}`);\n }\n styleEl.textContent = css;\n }\n}\n\n/**\n * Parse a full HTML document and extract its head elements and body\n * content separately, so they can be reassembled into a clean standalone\n * page without nesting `<html>` inside `<body>`.\n *\n * Extracts the full innerHTML of `<head>` — this preserves `<style>`,\n * `<script>`, `<link>`, `<meta>`, and any other head-level tags the\n * composition declares. Dropping `<link rel=\"stylesheet\">` or `<meta>`\n * would cause silent rendering failures for compositions that ship with\n * external CSS or viewport-dependent meta.\n *\n * `<html>` and `<body>` attributes (lang, class, data-*) are extracted\n * so callers can forward them to the assembled page.\n */\nfunction extractFullDocumentParts(\n rawHtml: string,\n compPath: string,\n): {\n headContent: string;\n bodyContent: string;\n htmlAttrs: string;\n bodyAttrs: string;\n} {\n const { document: doc } = parseHTML(rawHtml);\n\n const rewriteTargets = [doc.head, doc.body].filter(Boolean);\n for (const target of rewriteTargets) {\n rewriteRelativePaths(target, compPath);\n }\n // Run on the whole document: ids live in <body> but their rules may live in\n // a <head> <style>, so the scope must span both.\n fixDigitLeadingIdSelectors(doc);\n\n const headContent = doc.head?.innerHTML ?? \"\";\n const bodyContent = doc.body?.innerHTML ?? \"\";\n\n const htmlEl = doc.documentElement;\n const htmlAttrs = extractElementAttrs(htmlEl);\n const bodyAttrs = doc.body ? extractElementAttrs(doc.body) : \"\";\n\n return { headContent, bodyContent, htmlAttrs, bodyAttrs };\n}\n\n/**\n * Extract the inner HTML of the composition's wrapping `<template>` element, or\n * `null` if the source has no `<template>`.\n *\n * Located via the DOM rather than a regex. A greedy\n * `/<template[^>]*>([\\s\\S]*)<\\/template>/` can latch onto a literal\n * `\"<template>\"` that appears inside an HTML comment — e.g. a head note such as\n * \"the HF runtime clones ONLY <template> contents\" — and mis-slice the capture,\n * leaving the real composition content re-wrapped in an inert `<template>` in\n * the output. That template is never rendered by the browser, so the standalone\n * preview has no `[data-composition-id]` element and no registered timeline, and\n * renders blank. `querySelector(\"template\")` only ever matches a real element\n * node, so comment text can't fool it.\n */\nfunction extractTemplateInnerHtml(rawComp: string): string | null {\n const { document: doc } = parseHTML(rawComp);\n const template = doc.querySelector(\"template\");\n return template ? template.innerHTML : null;\n}\n\nfunction extractElementAttrs(el: Element): string {\n const parts: string[] = [];\n for (let i = 0; i < el.attributes.length; i++) {\n const attr = el.attributes[i]!;\n if (attr.value === \"\") {\n parts.push(attr.name);\n } else {\n parts.push(`${attr.name}=\"${attr.value}\"`);\n }\n }\n return parts.join(\" \");\n}\n\nconst NON_RENDERED_TAGS = new Set([\"SCRIPT\", \"STYLE\", \"LINK\", \"META\", \"TEMPLATE\", \"NOSCRIPT\"]);\n\n/**\n * Carry the `<template>`'s `data-composition-id` onto the content's root\n * rendered element when the author declared it only on the `<template>` tag.\n *\n * In a full composition, each sub-composition is mounted under a wrapper\n * element (the `data-composition-src` host) that carries the composition id,\n * which is how the runtime binds `window.__timelines[id]` into the player's\n * master timeline. A standalone preview has no such wrapper, so it relies on\n * the frame's own root element carrying `data-composition-id`. If the id lives\n * only on the inert `<template>` tag (a common authoring pattern), the rendered\n * body has no `[data-composition-id]` element — the runtime then never selects\n * a root composition, the registered GSAP timeline stays unbound, and seeking\n * does nothing. The frame renders at its pre-animation state (GSAP `fromTo`\n * pins `opacity:0`), producing a blank preview/thumbnail.\n *\n * This is a no-op when the content already exposes a `[data-composition-id]`\n * element (e.g. the id is authored on the root div), so compositions that\n * already render correctly are untouched.\n */\nfunction promoteTemplateCompositionId(rawComp: string, body: Element): void {\n const templateCompositionId = rawComp.match(\n /<template[^>]*\\sdata-composition-id\\s*=\\s*[\"']([^\"']+)[\"']/i,\n )?.[1];\n if (!templateCompositionId) return;\n if (body.querySelector(\"[data-composition-id]\")) return;\n\n const root = Array.from(body.children).find((el) => !NON_RENDERED_TAGS.has(el.tagName));\n root?.setAttribute(\"data-composition-id\", templateCompositionId);\n}\n\n/**\n * Add `data-composition-file=\"<compPath>\"` to the comp's root composition\n * element (the first `[data-composition-id]` that lacks the attribute), so the\n * studio resolves its top-level elements to the right source file. Idempotent;\n * a no-op when no composition element is present.\n */\nfunction tagRootCompositionFile(bodyHtml: string, compPath: string): string {\n const match = bodyHtml.match(/<[a-zA-Z][^>]*\\bdata-composition-id=/);\n if (match?.index == null) return bodyHtml;\n const tagEnd = bodyHtml.indexOf(\">\", match.index);\n if (tagEnd === -1) return bodyHtml;\n if (bodyHtml.slice(match.index, tagEnd).includes(\"data-composition-file\")) return bodyHtml;\n return (\n bodyHtml.slice(0, tagEnd) + ` data-composition-file=\"${compPath}\"` + bodyHtml.slice(tagEnd)\n );\n}\n\n/**\n * Build a standalone HTML page for a sub-composition.\n *\n * Uses the project's own index.html `<head>` so all dependencies (GSAP, fonts,\n * Lottie, reset styles, runtime) are preserved — instead of building a minimal\n * page from scratch that would miss important scripts/styles.\n *\n * Three dispatch modes, tried in order:\n * 1. `<template>` wrapper → extract template content (existing compositions)\n * 2. Full HTML document → parse and extract head/body separately (registry blocks)\n * 3. Raw fragment → wrap in a minimal document\n *\n * For full-doc mode, the composition's own `<head>` content (styles, scripts,\n * links, meta) is appended AFTER the project's index.html head. When both\n * declare the same dependency (e.g. GSAP CDN), the composition's copy wins\n * by last-write-wins script execution order — this is intentional so the\n * composition can pin a specific version.\n */\nexport function buildSubCompositionHtml(\n projectDir: string,\n compPath: string,\n runtimeUrl: string,\n baseHref?: string,\n): string | null {\n const compFile = join(projectDir, compPath);\n if (!existsSync(compFile)) return null;\n\n const rawComp = readFileSync(compFile, \"utf-8\");\n\n let compHeadContent = \"\";\n let rewrittenContent: string;\n let htmlAttrs = \"\";\n let bodyAttrs = \"\";\n\n const templateInner = extractTemplateInnerHtml(rawComp);\n\n if (templateInner != null) {\n const { document: contentDoc } = parseHTML(\n `<!DOCTYPE html><html><head></head><body>${templateInner}</body></html>`,\n );\n rewriteRelativePaths(contentDoc, compPath);\n fixDigitLeadingIdSelectors(contentDoc);\n promoteTemplateCompositionId(rawComp, contentDoc.body);\n rewrittenContent = contentDoc.body.innerHTML || templateInner;\n } else if (isFullHtmlDocument(rawComp)) {\n const parts = extractFullDocumentParts(rawComp, compPath);\n compHeadContent = parts.headContent;\n rewrittenContent = parts.bodyContent;\n htmlAttrs = parts.htmlAttrs;\n bodyAttrs = parts.bodyAttrs;\n } else {\n const { document: contentDoc } = parseHTML(\n `<!DOCTYPE html><html><head></head><body>${rawComp}</body></html>`,\n );\n rewriteRelativePaths(contentDoc, compPath);\n fixDigitLeadingIdSelectors(contentDoc);\n rewrittenContent = contentDoc.body.innerHTML || rawComp;\n }\n\n // A composition file may ship a baked inline runtime (from a prior export:\n // data-hyperframes-runtime / __hyperframeRuntime…). The studio injects its own\n // preview runtime below, so strip the baked one from the body — otherwise it's\n // double-loaded AND the baked inline copy can fail to parse inline (the\n // \"Unexpected token '<'\" SyntaxError seen on comps with a baked runtime).\n rewrittenContent = stripEmbeddedRuntimeScripts(rewrittenContent);\n\n // The comp's root carries data-composition-id but (unlike inlined sub-comps,\n // which inlineSubCompositions tags) no data-composition-file. Without it the\n // studio can't resolve which file this comp's top-level elements live in and\n // falls back to \"index.html\" — so the GSAP panel parses the project root (which\n // may be a multi-timeline master) and wrongly reports \"multiple timelines\",\n // disabling editing for a single-timeline comp. Tag the root with its own path.\n rewrittenContent = tagRootCompositionFile(rewrittenContent, compPath);\n\n // Use the project's index.html <head> to preserve all dependencies\n const indexPath = join(projectDir, \"index.html\");\n let headContent = \"\";\n\n if (existsSync(indexPath)) {\n const indexHtml = readFileSync(indexPath, \"utf-8\");\n const headMatch = indexHtml.match(/<head[^>]*>([\\s\\S]*?)<\\/head>/i);\n headContent = headMatch?.[1] ?? \"\";\n }\n\n // Inject <base> for relative asset resolution (before other tags)\n if (baseHref && !headContent.includes(\"<base\")) {\n headContent = `<base href=\"${baseHref}\">\\n${headContent}`;\n }\n\n // Append the sub-composition's own <head> content so its CSS, scripts,\n // links, and meta tags are preserved. Placed after the project head so\n // the composition's deps take precedence (last-write-wins for scripts).\n if (compHeadContent) headContent += `\\n${compHeadContent}`;\n\n // Strip any baked runtime the borrowed index/comp <head> carried, for the same\n // reason as the body above — done before injecting the preview runtime so the\n // injected tag (added next) is never removed.\n headContent = stripEmbeddedRuntimeScripts(headContent);\n\n // Ensure runtime is present (might differ from the one in index.html)\n if (\n !headContent.includes(\"hyperframe.runtime\") &&\n !headContent.includes(\"hyperframes-preview-runtime\")\n ) {\n headContent += `\\n<script data-hyperframes-preview-runtime=\"1\" src=\"${runtimeUrl}\"></script>`;\n }\n\n // Fallback: if no index.html head was found, add minimal deps\n if (!headContent.includes(\"gsap\")) {\n headContent += `\\n<script src=\"https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js\"></script>`;\n }\n\n const htmlOpen = htmlAttrs ? `<html ${htmlAttrs}>` : \"<html>\";\n const bodyOpen = bodyAttrs ? `<body ${bodyAttrs}>` : \"<body>\";\n\n return `<!DOCTYPE html>\n${htmlOpen}\n<head>\n${headContent}\n</head>\n${bodyOpen}\n<script>window.__timelines=window.__timelines||{};</script>\n${rewrittenContent}\n</body>\n</html>`;\n}\n","import { createHash } from \"node:crypto\";\nimport { lstatSync, readFileSync, readdirSync } from \"node:fs\";\nimport { extname, isAbsolute, relative, resolve } from \"node:path\";\n\nconst SIGNATURE_TEXT_EXTENSIONS = new Set([\n \".cjs\",\n \".css\",\n \".html\",\n \".js\",\n \".json\",\n \".jsx\",\n \".mjs\",\n \".svg\",\n \".ts\",\n \".tsx\",\n]);\nconst SIGNATURE_EXCLUDED_DIRS = new Set([\n \".cache\",\n \".git\",\n \".hyperframes\",\n \".next\",\n \".vite\",\n \"build\",\n \"coverage\",\n \"dist\",\n \"node_modules\",\n \"outputs\",\n \"renders\",\n]);\nconst MAX_SIGNATURE_TEXT_BYTES = 2_000_000;\nconst STUDIO_SIGNATURE_MANIFEST_PATHS = [\n \".hyperframes/studio-manual-edits.json\",\n \".hyperframes/studio-motion.json\",\n] as const;\n\ninterface ProjectSignatureFile {\n file: string;\n mtimeMs: number;\n size: number;\n textContentEligible: boolean;\n}\n\ninterface ProjectSignatureCacheEntry {\n fingerprint: string;\n signature: string;\n}\n\nconst projectSignatureCache = new Map<string, ProjectSignatureCacheEntry>();\n\nfunction isPathWithin(parentDir: string, childPath: string): boolean {\n const childRelativePath = relative(parentDir, childPath);\n return (\n childRelativePath === \"\" ||\n (!childRelativePath.startsWith(\"..\") && !isAbsolute(childRelativePath))\n );\n}\n\nfunction isTextContentEligible(file: string, size: number): boolean {\n return (\n SIGNATURE_TEXT_EXTENSIONS.has(extname(file).toLowerCase()) && size <= MAX_SIGNATURE_TEXT_BYTES\n );\n}\n\nfunction collectProjectSignatureFiles(\n projectDir: string,\n dir: string,\n files: ProjectSignatureFile[],\n): void {\n let entries: string[];\n try {\n entries = readdirSync(dir).sort();\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (SIGNATURE_EXCLUDED_DIRS.has(entry)) continue;\n const file = resolve(dir, entry);\n if (!isPathWithin(projectDir, file)) continue;\n let stat: ReturnType<typeof lstatSync>;\n try {\n stat = lstatSync(file);\n } catch {\n continue;\n }\n if (stat.isSymbolicLink()) continue;\n if (stat.isDirectory()) {\n collectProjectSignatureFiles(projectDir, file, files);\n } else if (stat.isFile()) {\n files.push({\n file,\n mtimeMs: stat.mtimeMs,\n size: stat.size,\n textContentEligible: isTextContentEligible(file, stat.size),\n });\n }\n }\n}\n\nfunction collectProjectSignatureManifestFiles(\n projectDir: string,\n files: ProjectSignatureFile[],\n): void {\n const seen = new Set(files.map((entry) => entry.file));\n for (const manifestPath of STUDIO_SIGNATURE_MANIFEST_PATHS) {\n const file = resolve(projectDir, manifestPath);\n if (seen.has(file) || !isPathWithin(projectDir, file)) continue;\n let stat: ReturnType<typeof lstatSync>;\n try {\n stat = lstatSync(file);\n } catch {\n continue;\n }\n if (stat.isSymbolicLink() || !stat.isFile()) continue;\n files.push({\n file,\n mtimeMs: stat.mtimeMs,\n size: stat.size,\n textContentEligible: isTextContentEligible(file, stat.size),\n });\n seen.add(file);\n }\n}\n\nfunction createProjectFingerprint(projectDir: string, files: ProjectSignatureFile[]): string {\n const hash = createHash(\"sha256\");\n for (const entry of files) {\n hash.update(relative(projectDir, entry.file));\n hash.update(\"\\0\");\n hash.update(String(entry.size));\n hash.update(\"\\0\");\n hash.update(String(entry.mtimeMs));\n hash.update(\"\\0\");\n hash.update(entry.textContentEligible ? \"text\" : \"binary\");\n hash.update(\"\\0\");\n }\n return hash.digest(\"hex\").slice(0, 24);\n}\n\n/**\n * Creates a stable preview cache-busting signature for project source plus Studio manifests.\n */\nexport function createProjectSignature(projectDir: string): string {\n const normalizedProjectDir = resolve(projectDir);\n const files: ProjectSignatureFile[] = [];\n collectProjectSignatureFiles(normalizedProjectDir, normalizedProjectDir, files);\n collectProjectSignatureManifestFiles(normalizedProjectDir, files);\n files.sort((a, b) => a.file.localeCompare(b.file));\n\n const fingerprint = createProjectFingerprint(normalizedProjectDir, files);\n const cached = projectSignatureCache.get(normalizedProjectDir);\n if (cached?.fingerprint === fingerprint) return cached.signature;\n\n const hash = createHash(\"sha256\");\n for (const entry of files) {\n const relativePath = relative(normalizedProjectDir, entry.file);\n hash.update(relativePath);\n hash.update(\"\\0\");\n hash.update(String(entry.size));\n hash.update(\"\\0\");\n if (entry.textContentEligible) {\n try {\n hash.update(readFileSync(entry.file));\n } catch {\n hash.update(String(entry.mtimeMs));\n }\n } else {\n hash.update(String(entry.mtimeMs));\n }\n hash.update(\"\\0\");\n }\n const signature = hash.digest(\"hex\").slice(0, 24);\n projectSignatureCache.set(normalizedProjectDir, { fingerprint, signature });\n return signature;\n}\n","export interface StudioMotionRenderScriptOptions {\n activeCompositionPath?: string | null;\n}\n\nexport const STUDIO_MOTION_PATH = \".hyperframes/studio-motion.json\";\n\nfunction hasStudioMotionEntries(manifestContent: string): boolean {\n try {\n const parsed = JSON.parse(manifestContent) as { motions?: unknown };\n return Array.isArray(parsed.motions) && parsed.motions.length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Builds the render-time Studio motion runtime script, or null when no owned motion exists.\n */\nexport function createStudioMotionRenderBodyScript(\n manifestContent: string,\n options: StudioMotionRenderScriptOptions = {},\n): string | null {\n if (!manifestContent.trim() || !hasStudioMotionEntries(manifestContent)) return null;\n return `(${studioMotionRenderRuntime.toString()})(${JSON.stringify(manifestContent)}, ${JSON.stringify(options.activeCompositionPath ?? null)});`;\n}\n\nfunction studioMotionRenderRuntime(\n manifestContent: string,\n activeCompositionPath: string | null,\n): void {\n const STUDIO_MOTION_TIMELINE_ID = \"studio-motion\";\n const STUDIO_MOTION_ATTR = \"data-hf-studio-motion\";\n const ORIGINAL_TRANSFORM_ATTR = \"data-hf-studio-motion-original-transform\";\n const ORIGINAL_OPACITY_ATTR = \"data-hf-studio-motion-original-opacity\";\n const ORIGINAL_VISIBILITY_ATTR = \"data-hf-studio-motion-original-visibility\";\n\n const objectRecord = (value: unknown): Record<string, unknown> | null =>\n value && typeof value === \"object\" ? (value as Record<string, unknown>) : null;\n\n const finiteNumber = (value: unknown): number | null =>\n typeof value === \"number\" && Number.isFinite(value) ? value : null;\n\n const runtimeWindow = window as Window & {\n gsap?: {\n timeline?: (vars?: Record<string, unknown>) => {\n fromTo?: (\n target: HTMLElement,\n from: Record<string, unknown>,\n to: Record<string, unknown>,\n at: number,\n ) => unknown;\n totalTime?: (time: number, suppressEvents?: boolean) => unknown;\n time?: (time: number) => unknown;\n pause?: () => unknown;\n kill?: () => unknown;\n };\n set?: (target: HTMLElement, vars: Record<string, unknown>) => unknown;\n registerPlugin?: (...plugins: unknown[]) => unknown;\n };\n CustomEase?: { create?: (id: string, data: string) => unknown };\n __player?: { getTime?: () => number };\n __timeline?: { time?: () => number };\n __timelines?: Record<\n string,\n | {\n kill?: () => unknown;\n }\n | undefined\n >;\n __hfStudioMotionApply?: () => number;\n };\n\n const parseMotionValues = (value: unknown): Record<string, number> | null => {\n const record = objectRecord(value);\n if (!record) return null;\n const parsed: Record<string, number> = {};\n for (const key of [\"x\", \"y\", \"scale\", \"rotation\", \"opacity\", \"autoAlpha\"]) {\n const next = finiteNumber(record[key]);\n if (next != null) parsed[key] = next;\n }\n return Object.keys(parsed).length > 0 ? parsed : null;\n };\n\n const parseCustomEase = (value: unknown): { id: string; data: string } | null => {\n const record = objectRecord(value);\n if (!record) return null;\n const id = typeof record.id === \"string\" ? record.id.trim() : \"\";\n const data = typeof record.data === \"string\" ? record.data.trim() : \"\";\n if (!id || !data) return null;\n return { id, data };\n };\n\n const parsedManifest = (() => {\n try {\n return objectRecord(JSON.parse(manifestContent));\n } catch {\n return null;\n }\n })();\n const manifestMotions = Array.isArray(parsedManifest?.motions) ? parsedManifest.motions : [];\n\n const sourceFileForElement = (element: HTMLElement): string => {\n let current: HTMLElement | null = element;\n while (current) {\n const sourceFile =\n current.getAttribute(\"data-composition-file\") ??\n current.getAttribute(\"data-composition-src\");\n if (sourceFile) return sourceFile;\n current = current.parentElement;\n }\n return activeCompositionPath ?? \"index.html\";\n };\n\n const elementMatchesSourceFile = (element: HTMLElement, sourceFile: string): boolean =>\n sourceFileForElement(element) === sourceFile;\n\n const isHTMLElement = (element: Element | null): element is HTMLElement =>\n element instanceof HTMLElement;\n\n const querySelectorCandidates = (selector: string): HTMLElement[] => {\n const className = selector.match(/^\\.([A-Za-z0-9_-]+)$/)?.[1];\n if (className) {\n return Array.from(document.getElementsByTagName(\"*\")).filter(\n (element): element is HTMLElement =>\n isHTMLElement(element) && element.classList.contains(className),\n );\n }\n if (/^[A-Za-z][A-Za-z0-9-]*$/.test(selector)) {\n return Array.from(document.getElementsByTagName(selector)).filter(isHTMLElement);\n }\n return Array.from(document.querySelectorAll(selector)).filter(isHTMLElement);\n };\n\n const resolveTarget = (targetRecord: Record<string, unknown>): HTMLElement | null => {\n const sourceFile = typeof targetRecord.sourceFile === \"string\" ? targetRecord.sourceFile : \"\";\n if (!sourceFile) return null;\n const id = typeof targetRecord.id === \"string\" ? targetRecord.id : \"\";\n if (id) {\n const byId = document.getElementById(id);\n if (isHTMLElement(byId) && elementMatchesSourceFile(byId, sourceFile)) return byId;\n }\n const selector = typeof targetRecord.selector === \"string\" ? targetRecord.selector : \"\";\n if (!selector) return null;\n try {\n const selectorIndex = Math.max(0, Math.floor(finiteNumber(targetRecord.selectorIndex) ?? 0));\n return (\n querySelectorCandidates(selector).filter((element) =>\n elementMatchesSourceFile(element, sourceFile),\n )[selectorIndex] ?? null\n );\n } catch {\n return null;\n }\n };\n\n const restoreElement = (element: HTMLElement): void => {\n runtimeWindow.gsap?.set?.(element, { clearProps: \"transform,opacity,visibility\" });\n element.style.transform = element.getAttribute(ORIGINAL_TRANSFORM_ATTR) ?? \"\";\n element.style.opacity = element.getAttribute(ORIGINAL_OPACITY_ATTR) ?? \"\";\n element.style.visibility = element.getAttribute(ORIGINAL_VISIBILITY_ATTR) ?? \"\";\n element.removeAttribute(STUDIO_MOTION_ATTR);\n element.removeAttribute(ORIGINAL_TRANSFORM_ATTR);\n element.removeAttribute(ORIGINAL_OPACITY_ATTR);\n element.removeAttribute(ORIGINAL_VISIBILITY_ATTR);\n };\n\n const restoreStudioMotionElements = (): void => {\n for (const element of Array.from(document.querySelectorAll(`[${STUDIO_MOTION_ATTR}]`))) {\n if (isHTMLElement(element)) restoreElement(element);\n }\n };\n\n const readCurrentTime = (): number => {\n try {\n const playerTime = runtimeWindow.__player?.getTime?.();\n if (typeof playerTime === \"number\" && Number.isFinite(playerTime)) {\n return Math.max(0, playerTime);\n }\n } catch {\n // fall through\n }\n try {\n const timelineTime = runtimeWindow.__timeline?.time?.();\n if (typeof timelineTime === \"number\" && Number.isFinite(timelineTime)) {\n return Math.max(0, timelineTime);\n }\n } catch {\n // fall through\n }\n return 0;\n };\n\n const resolveEase = (motion: Record<string, unknown>): string => {\n const fallback =\n typeof motion.ease === \"string\" && motion.ease.trim() ? motion.ease.trim() : \"none\";\n const customEase = parseCustomEase(motion.customEase);\n const customEasePlugin = runtimeWindow.CustomEase;\n if (!customEase || typeof customEasePlugin?.create !== \"function\") return fallback;\n try {\n runtimeWindow.gsap?.registerPlugin?.(customEasePlugin);\n customEasePlugin.create(customEase.id, customEase.data);\n return customEase.id;\n } catch {\n return fallback;\n }\n };\n\n const applyManifest = (): number => {\n runtimeWindow.__timelines = runtimeWindow.__timelines ?? {};\n runtimeWindow.__timelines[STUDIO_MOTION_TIMELINE_ID]?.kill?.();\n delete runtimeWindow.__timelines[STUDIO_MOTION_TIMELINE_ID];\n restoreStudioMotionElements();\n const gsap = runtimeWindow.gsap;\n if (!gsap?.timeline || manifestMotions.length === 0) return 0;\n\n const timeline = gsap.timeline({ paused: true, defaults: { overwrite: \"auto\" } });\n let applied = 0;\n for (const motionValue of manifestMotions) {\n const motion = objectRecord(motionValue);\n if (!motion || motion.kind !== \"gsap-motion\") continue;\n const targetRecord = objectRecord(motion.target);\n if (!targetRecord) continue;\n const target = resolveTarget(targetRecord);\n if (!target || typeof timeline.fromTo !== \"function\") continue;\n const start = finiteNumber(motion.start);\n const duration = finiteNumber(motion.duration);\n if (start == null || duration == null || start < 0 || duration <= 0) continue;\n const from = parseMotionValues(motion.from);\n const to = parseMotionValues(motion.to);\n if (!from || !to) continue;\n if (!target.hasAttribute(STUDIO_MOTION_ATTR)) {\n target.setAttribute(ORIGINAL_TRANSFORM_ATTR, target.style.transform);\n target.setAttribute(ORIGINAL_OPACITY_ATTR, target.style.opacity);\n target.setAttribute(ORIGINAL_VISIBILITY_ATTR, target.style.visibility);\n }\n target.setAttribute(STUDIO_MOTION_ATTR, \"true\");\n timeline.fromTo(\n target,\n from,\n { ...to, duration, ease: resolveEase(motion), overwrite: \"auto\", immediateRender: false },\n start,\n );\n applied += 1;\n }\n\n if (applied === 0) {\n timeline.kill?.();\n return 0;\n }\n runtimeWindow.__timelines[STUDIO_MOTION_TIMELINE_ID] = timeline;\n timeline.pause?.();\n const currentTime = readCurrentTime();\n if (typeof timeline.totalTime === \"function\") timeline.totalTime(currentTime, false);\n else timeline.time?.(currentTime);\n return applied;\n };\n\n runtimeWindow.__hfStudioMotionApply = applyManifest;\n applyManifest();\n}\n","import { ensureHfIds } from \"@hyperframes/parsers/hf-ids\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\n\n/**\n * Ensure `html` has `data-hf-id` attributes minted, and write the result back\n * to `filePath` if new ids were added.\n *\n * **Invariant:** `html` must be the raw file content read from `filePath` just\n * before this call. If `html` is constructed or transformed HTML the TOCTOU\n * guard (`current === html`) will never match and writes will silently be\n * skipped — no ids will reach disk.\n */\nexport function persistHfIdsIfNeeded(filePath: string, html: string): string {\n const normalized = ensureHfIds(html);\n // Use attribute count instead of string equality: linkedom serialization may\n // normalize quote style and whitespace even when no ids were actually minted,\n // which would cause spurious writes on every request.\n const idsBefore = (html.match(/\\bdata-hf-id=/g) ?? []).length;\n const idsAfter = (normalized.match(/\\bdata-hf-id=/g) ?? []).length;\n if (idsAfter > idsBefore) {\n try {\n // Re-read before writing to guard against concurrent user saves. If the\n // file changed since we read it, skip the write — serving with ids is\n // still correct; the next request will re-persist. Best-effort only: a\n // user save landing between readFileSync and writeFileSync below can\n // still be overwritten (microsecond window).\n const current = readFileSync(filePath, \"utf-8\");\n if (current === html) {\n writeFileSync(filePath, normalized, \"utf-8\");\n }\n } catch (err) {\n // Non-fatal — serve with ids even if the disk write fails (e.g. read-only\n // filesystem, sandboxed environment). Log so the failure is diagnosable.\n console.warn(\"[hyperframes] persistHfIdsIfNeeded: failed to write ids to disk:\", err);\n }\n }\n return normalized;\n}\n","import type { Hono } from \"hono\";\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { StudioApiAdapter } from \"../types.js\";\nimport { isInHiddenOrVendorDir, walkDir } from \"../helpers/safePath.js\";\n\nexport function registerLintRoutes(api: Hono, adapter: StudioApiAdapter): void {\n api.get(\"/projects/:id/lint\", async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n try {\n const htmlFiles = walkDir(project.dir).filter(\n (f) => f.endsWith(\".html\") && !isInHiddenOrVendorDir(f),\n );\n const allFindings: Array<{\n severity: string;\n message: string;\n file?: string;\n fixHint?: string;\n }> = [];\n for (const file of htmlFiles) {\n const content = readFileSync(join(project.dir, file), \"utf-8\");\n const result = await adapter.lint(content, { filePath: file });\n if (result?.findings) {\n for (const f of result.findings) {\n allFindings.push({ ...f, file });\n }\n }\n }\n return c.json({ findings: allFindings });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return c.json({ error: `Lint failed: ${msg}` }, 500);\n }\n });\n}\n","import type { Hono } from \"hono\";\nimport { streamSSE } from \"hono/streaming\";\nimport { existsSync, readFileSync, mkdirSync, unlinkSync, readdirSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { StudioApiAdapter, RenderJobState } from \"../types.js\";\nimport { VALID_CANVAS_RESOLUTIONS, type CanvasResolution } from \"@hyperframes/parsers\";\nimport { parseFps } from \"@hyperframes/core\";\nimport { resolveWithinProject } from \"../helpers/safePath.js\";\n\nconst VALID_RESOLUTIONS = new Set<string>(VALID_CANVAS_RESOLUTIONS);\n\nexport function registerRenderRoutes(api: Hono, adapter: StudioApiAdapter): void {\n // Scoped job store — not shared across createStudioApi() calls\n const renderJobs = new Map<string, RenderJobState & { createdAt: number }>();\n\n // TTL cleanup for completed jobs (5 minutes)\n const TTL_MS = 300_000;\n const CLEANUP_INTERVAL_MS = 60_000;\n let cleanupTimer: ReturnType<typeof setInterval> | null = null;\n\n const cleanupEnabled = () =>\n typeof process !== \"undefined\" &&\n process.env.NODE_ENV !== \"production\" &&\n !process.argv.includes(\"build\");\n\n const cleanupFinishedJobs = () => {\n const now = Date.now();\n for (const [key, job] of renderJobs) {\n if ((job.status === \"complete\" || job.status === \"failed\") && now - job.createdAt > TTL_MS) {\n renderJobs.delete(key);\n }\n }\n if (renderJobs.size === 0 && cleanupTimer) {\n clearInterval(cleanupTimer);\n cleanupTimer = null;\n }\n };\n\n const ensureCleanupTimer = () => {\n if (cleanupTimer || !cleanupEnabled()) return;\n cleanupTimer = setInterval(cleanupFinishedJobs, CLEANUP_INTERVAL_MS);\n if (typeof cleanupTimer === \"object\" && \"unref\" in cleanupTimer) {\n cleanupTimer.unref();\n }\n };\n\n ensureCleanupTimer();\n\n // Start a render\n api.post(\"/projects/:id/render\", async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n\n const body = (await c.req.json().catch(() => ({}))) as {\n // Polymorphic per design note in core.types.Fps:\n // number → integer fps (e.g. 30)\n // string → rational fps (e.g. \"30000/1001\" for NTSC 29.97)\n // Decimals are rejected on purpose so the exact denominator stays\n // unambiguous (29.97 ≠ 30000/1001 when ffmpeg consumes them).\n fps?: number | string;\n quality?: string;\n format?: string;\n resolution?: string;\n composition?: string;\n // Browser telemetry id, so the server-emitted render outcome is\n // attributed to the user who triggered the render (joinable funnel).\n telemetryDistinctId?: string;\n };\n const VALID_FORMATS = new Set([\"mp4\", \"webm\", \"mov\"]);\n const FORMAT_EXT: Record<string, string> = { mp4: \".mp4\", webm: \".webm\", mov: \".mov\" };\n const format = VALID_FORMATS.has(body.format ?? \"\") ? (body.format as string) : \"mp4\";\n\n // Default to 30 fps when unset or unparseable. The route stays lenient on\n // invalid fps values (matching the lenient handling of `resolution` and\n // `quality` already in this file) — the producer surfaces a clearer error\n // message if the caller really did mean to fail loudly.\n const fpsParse = body.fps === undefined ? null : parseFps(body.fps);\n const fps = fpsParse && fpsParse.ok ? fpsParse.value : { num: 30, den: 1 };\n const quality = [\"draft\", \"standard\", \"high\"].includes(body.quality ?? \"\")\n ? (body.quality as string)\n : \"standard\";\n const outputResolution = VALID_RESOLUTIONS.has(body.resolution ?? \"\")\n ? (body.resolution as CanvasResolution)\n : undefined;\n let composition: string | undefined;\n if (typeof body.composition === \"string\" && body.composition.length > 0) {\n // `body.composition` is attacker-controlled (from c.req.json()).\n // resolveWithinProject dereferences symlinks, so an in-project symlink\n // pointing outside the root can't smuggle the render target out.\n if (!resolveWithinProject(project.dir, body.composition)) {\n return c.json({ error: \"composition path must be within the project directory\" }, 400);\n }\n composition = body.composition;\n }\n\n // fallow-ignore-next-line code-duplication\n const now = new Date();\n const datePart = now.toISOString().slice(0, 10);\n const timePart = now.toTimeString().slice(0, 8).replace(/:/g, \"-\");\n const jobId = `${project.id}_${datePart}_${timePart}`;\n const rendersDir = adapter.rendersDir(project);\n if (!existsSync(rendersDir)) mkdirSync(rendersDir, { recursive: true });\n const ext = FORMAT_EXT[format] ?? \".mp4\";\n const outputPath = join(rendersDir, `${jobId}${ext}`);\n\n const jobState = adapter.startRender({\n project,\n outputPath,\n format: format as \"mp4\" | \"webm\" | \"mov\",\n fps,\n quality,\n jobId,\n outputResolution,\n composition,\n distinctId:\n typeof body.telemetryDistinctId === \"string\" ? body.telemetryDistinctId : undefined,\n });\n (jobState as RenderJobState & { createdAt: number }).createdAt = Date.now();\n renderJobs.set(jobId, jobState as RenderJobState & { createdAt: number });\n\n ensureCleanupTimer();\n\n return c.json({ jobId, status: \"rendering\" });\n });\n\n // SSE progress stream\n api.get(\"/render/:jobId/progress\", (c) => {\n const { jobId } = c.req.param();\n const job = renderJobs.get(jobId);\n if (!job) return c.json({ error: \"not found\" }, 404);\n\n return streamSSE(c, async (stream) => {\n while (true) {\n const current = renderJobs.get(jobId);\n if (!current) break;\n await stream.writeSSE({\n event: \"progress\",\n data: JSON.stringify({\n progress: current.progress,\n status: current.status,\n stage: current.stage,\n error: current.error,\n }),\n });\n if (current.status === \"complete\" || current.status === \"failed\") break;\n await stream.sleep(500);\n }\n });\n });\n\n const RENDER_MIME: Record<string, string> = {\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mov\": \"video/quicktime\",\n };\n const RENDER_EXTENSIONS = Object.keys(RENDER_MIME);\n\n function renderContentType(filePath: string): string {\n const ext = RENDER_EXTENSIONS.find((e) => filePath.endsWith(e));\n return (ext && RENDER_MIME[ext]) ?? \"video/mp4\";\n }\n\n // Serve render inline (for in-browser playback — opens in a new tab)\n api.get(\"/render/:jobId/view\", (c) => {\n const { jobId } = c.req.param();\n const job = renderJobs.get(jobId);\n if (!job?.outputPath || !existsSync(job.outputPath)) {\n return c.json({ error: \"not found\" }, 404);\n }\n const contentType = renderContentType(job.outputPath);\n const filename = job.outputPath.split(\"/\").pop() ?? `render.mp4`;\n const content = readFileSync(job.outputPath);\n return new Response(content, {\n headers: {\n \"Content-Type\": contentType,\n \"Content-Disposition\": `inline; filename=\"${filename}\"`,\n \"Accept-Ranges\": \"bytes\",\n \"Content-Length\": String(content.length),\n },\n });\n });\n\n // Download render\n api.get(\"/render/:jobId/download\", (c) => {\n const { jobId } = c.req.param();\n const job = renderJobs.get(jobId);\n if (!job?.outputPath || !existsSync(job.outputPath)) {\n return c.json({ error: \"not found\" }, 404);\n }\n const contentType = renderContentType(job.outputPath);\n const filename = job.outputPath.split(\"/\").pop() ?? `render.mp4`;\n const content = readFileSync(job.outputPath);\n return new Response(content, {\n headers: {\n \"Content-Type\": contentType,\n \"Content-Disposition\": `attachment; filename=\"${filename}\"`,\n },\n });\n });\n\n // Delete render\n api.delete(\"/render/:jobId\", (c) => {\n const { jobId } = c.req.param();\n for (const [, state] of renderJobs) {\n if (state.id === jobId && state.outputPath) {\n const dir = state.outputPath.replace(/\\/[^/]+$/, \"\");\n for (const ext of [\".mp4\", \".webm\", \".mov\", \".meta.json\"]) {\n const fp = join(dir, `${jobId}${ext}`);\n if (existsSync(fp)) unlinkSync(fp);\n }\n break;\n }\n }\n renderJobs.delete(jobId);\n return c.json({ deleted: true });\n });\n\n // Serve render file directly from disk (no in-memory map dependency)\n api.get(\"/projects/:id/renders/file/*\", async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n const filename = c.req.path.split(\"/renders/file/\")[1];\n if (!filename) return c.json({ error: \"missing filename\" }, 400);\n const rendersDir = adapter.rendersDir(project);\n // Containment guard: the filename is attacker-controlled wildcard input, so\n // route it through the same chokepoint every other project-scoped path uses.\n // Literal `..` is collapsed upstream by the URL parser, but a bare join() +\n // readFileSync still followed an in-rendersDir symlink pointing outside the\n // dir; resolveWithinProject canonicalizes with realpath before serving.\n const fp = resolveWithinProject(rendersDir, filename);\n if (!fp) return c.json({ error: \"forbidden\" }, 403);\n if (!existsSync(fp)) return c.json({ error: \"not found\" }, 404);\n const contentType = renderContentType(fp);\n const content = readFileSync(fp);\n return new Response(content, {\n headers: {\n \"Content-Type\": contentType,\n \"Content-Disposition\": `inline; filename=\"${filename}\"`,\n \"Accept-Ranges\": \"bytes\",\n \"Content-Length\": String(content.length),\n },\n });\n });\n\n // List renders\n api.get(\"/projects/:id/renders\", async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n const rendersDir = adapter.rendersDir(project);\n if (!existsSync(rendersDir)) return c.json({ renders: [] });\n const files = readdirSync(rendersDir)\n .filter((f) => f.endsWith(\".mp4\") || f.endsWith(\".webm\") || f.endsWith(\".mov\"))\n .map((f) => {\n const fp = join(rendersDir, f);\n const stat = statSync(fp);\n const rid = f.replace(/\\.(mp4|webm|mov)$/, \"\");\n const metaPath = join(rendersDir, `${rid}.meta.json`);\n let status: \"complete\" | \"failed\" = \"complete\";\n let durationMs: number | undefined;\n if (existsSync(metaPath)) {\n try {\n const meta = JSON.parse(readFileSync(metaPath, \"utf-8\"));\n if (meta.status === \"failed\") status = \"failed\";\n if (meta.durationMs) durationMs = meta.durationMs;\n } catch {\n /* ignore */\n }\n }\n return {\n id: rid,\n filename: f,\n size: stat.size,\n createdAt: stat.mtimeMs,\n status,\n durationMs,\n };\n })\n .sort((a, b) => b.createdAt - a.createdAt);\n // Register on-disk renders that aren't in the current session's job map\n // so they remain downloadable after a server restart.\n for (const file of files) {\n if (!renderJobs.has(file.id)) {\n renderJobs.set(file.id, {\n id: file.id,\n status: file.status,\n progress: 100,\n outputPath: join(rendersDir, file.filename),\n createdAt: file.createdAt,\n } as RenderJobState & { createdAt: number });\n }\n }\n return c.json({ renders: files });\n });\n}\n","import type { Hono } from \"hono\";\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport type { StudioApiAdapter } from \"../types.js\";\nimport { STUDIO_MANUAL_EDITS_PATH } from \"../helpers/manualEditsRenderScript.js\";\nimport { STUDIO_MOTION_PATH } from \"../helpers/studioMotionRenderScript.js\";\n\nconst THUMBNAIL_CACHE_VERSION = \"v4\";\n\nexport function registerThumbnailRoutes(api: Hono, adapter: StudioApiAdapter): void {\n api.get(\"/projects/:id/thumbnail/*\", async (c) => {\n if (!adapter.generateThumbnail) {\n return c.json({ error: \"Thumbnails not available\" }, 501);\n }\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n\n let compPath = decodeURIComponent(\n c.req.path.replace(`/projects/${project.id}/thumbnail/`, \"\").split(\"?\")[0] ?? \"\",\n );\n if (compPath && !compPath.includes(\".\")) compPath += \".html\";\n\n const url = new URL(c.req.url, `http://${c.req.header(\"host\") || \"localhost\"}`);\n const rawSeekTime = url.searchParams.get(\"t\");\n const parsedSeekTime = rawSeekTime == null ? Number.NaN : parseFloat(rawSeekTime);\n const seekTime = Number.isFinite(parsedSeekTime) ? parsedSeekTime : 0.5;\n const vpWidth = parseInt(url.searchParams.get(\"w\") || \"0\") || 0;\n const vpHeight = parseInt(url.searchParams.get(\"h\") || \"0\") || 0;\n const selector = url.searchParams.get(\"selector\") || undefined;\n const format = url.searchParams.get(\"format\") === \"png\" ? \"png\" : \"jpeg\";\n const contentType = format === \"png\" ? \"image/png\" : \"image/jpeg\";\n const rawSelectorIndex = Number.parseInt(url.searchParams.get(\"selectorIndex\") || \"0\", 10);\n const selectorIndex =\n Number.isFinite(rawSelectorIndex) && rawSelectorIndex > 0 ? rawSelectorIndex : undefined;\n const urlVersion = url.searchParams.get(\"v\") || \"\";\n\n // Determine composition dimensions from HTML\n let compW = vpWidth || 1920;\n let compH = vpHeight || 1080;\n let sourceMtime = 0;\n if (!vpWidth) {\n const htmlFile = join(project.dir, compPath);\n if (existsSync(htmlFile)) {\n sourceMtime = Math.round(statSync(htmlFile).mtimeMs);\n const html = readFileSync(htmlFile, \"utf-8\");\n const wMatch = html.match(/data-width=[\"'](\\d+)[\"']/);\n const hMatch = html.match(/data-height=[\"'](\\d+)[\"']/);\n if (wMatch?.[1]) compW = parseInt(wMatch[1]);\n if (hMatch?.[1]) compH = parseInt(hMatch[1]);\n }\n }\n const manualEditsFile = join(project.dir, STUDIO_MANUAL_EDITS_PATH);\n let manualEditsKey = \"\";\n if (existsSync(manualEditsFile)) {\n const manualEditsContent = readFileSync(manualEditsFile, \"utf-8\");\n manualEditsKey = `_${createHash(\"sha1\").update(manualEditsContent).digest(\"hex\").slice(0, 16)}`;\n sourceMtime = Math.max(sourceMtime, Math.round(statSync(manualEditsFile).mtimeMs));\n }\n const motionFile = join(project.dir, STUDIO_MOTION_PATH);\n let motionKey = \"\";\n if (existsSync(motionFile)) {\n const motionContent = readFileSync(motionFile, \"utf-8\");\n motionKey = `_${createHash(\"sha1\").update(motionContent).digest(\"hex\").slice(0, 16)}`;\n sourceMtime = Math.max(sourceMtime, Math.round(statSync(motionFile).mtimeMs));\n }\n\n const previewUrl =\n compPath === \"index.html\"\n ? `http://${c.req.header(\"host\")}/api/projects/${project.id}/preview`\n : `http://${c.req.header(\"host\")}/api/projects/${project.id}/preview/comp/${compPath}`;\n\n // Cache\n const cacheDir = join(project.dir, \".thumbnails\");\n const selectorKey = selector\n ? `_${selector.replace(/[^a-zA-Z0-9_-]+/g, \"_\").slice(0, 80)}_${selectorIndex ?? 0}`\n : \"\";\n const urlVersionKey = urlVersion\n ? `_${urlVersion.replace(/[^a-zA-Z0-9_-]+/g, \"_\").slice(0, 32)}`\n : \"\";\n const cacheKey = `${THUMBNAIL_CACHE_VERSION}${urlVersionKey}${manualEditsKey}${motionKey}_${format}_${compPath.replace(/\\//g, \"_\")}_${compW}x${compH}_${sourceMtime}_${seekTime.toFixed(2)}${selectorKey}.${format === \"png\" ? \"png\" : \"jpg\"}`;\n const cachePath = join(cacheDir, cacheKey);\n if (existsSync(cachePath)) {\n return new Response(new Uint8Array(readFileSync(cachePath)), {\n headers: { \"Content-Type\": contentType, \"Cache-Control\": \"public, max-age=60\" },\n });\n }\n\n try {\n const buffer = await adapter.generateThumbnail({\n project,\n compPath,\n seekTime,\n width: compW,\n height: compH,\n previewUrl,\n selector,\n format,\n selectorIndex,\n });\n if (!buffer) {\n return c.json(\n { error: \"Thumbnail generation failed — Chrome browser may not be available\" },\n 500,\n );\n }\n if (!existsSync(cacheDir)) mkdirSync(cacheDir, { recursive: true });\n writeFileSync(cachePath, buffer);\n return new Response(new Uint8Array(buffer), {\n headers: { \"Content-Type\": contentType, \"Cache-Control\": \"public, max-age=60\" },\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return c.json({ error: `Thumbnail generation failed: ${msg}` }, 500);\n }\n });\n}\n","// fallow-ignore-file code-duplication\nexport interface StudioManualEditsRenderScriptOptions {\n activeCompositionPath?: string | null;\n}\n\nexport const STUDIO_MANUAL_EDITS_PATH = \".hyperframes/studio-manual-edits.json\";\n\nexport function createStudioManualEditsRenderBodyScript(\n manifestContent: string,\n options: StudioManualEditsRenderScriptOptions = {},\n): string | null {\n if (!manifestContent.trim()) return null;\n return `(${studioManualEditsRenderRuntime.toString()})(${JSON.stringify(manifestContent)}, ${JSON.stringify(options.activeCompositionPath ?? null)});`;\n}\n\n/**\n * Returns a self-contained IIFE string that re-applies studio position edits\n * (translate, rotate) after every GSAP seek by querying data attributes baked\n * into the HTML. Works without a JSON manifest — positions are already inlined\n * as CSS custom properties on the elements.\n */\nexport function createStudioPositionSeekReapplyScript(): string {\n return `(${studioPositionSeekReapplyRuntime.toString()})();`;\n}\n\nfunction studioPositionSeekReapplyRuntime(): void {\n const OFFSET_X_PROP = \"--hf-studio-offset-x\";\n const OFFSET_Y_PROP = \"--hf-studio-offset-y\";\n const WIDTH_PROP = \"--hf-studio-width\";\n const HEIGHT_PROP = \"--hf-studio-height\";\n const ROTATION_PROP = \"--hf-studio-rotation\";\n const PATH_OFFSET_ATTR = \"data-hf-studio-path-offset\";\n const BOX_SIZE_ATTR = \"data-hf-studio-box-size\";\n const ROTATION_ATTR = \"data-hf-studio-rotation\";\n const ORIGINAL_TRANSLATE_ATTR = \"data-hf-studio-original-translate\";\n const ORIGINAL_ROTATE_ATTR = \"data-hf-studio-original-rotate\";\n const MOTION_ATTR = \"data-hf-studio-motion\";\n const MOTION_TL_KEY = \"studio-motion\";\n const WRAPPED_PROP = \"__hfStudioPositionSeekReapplyWrapped\";\n\n if (\n !document.querySelector(\"[\" + PATH_OFFSET_ATTR + '=\"true\"]') &&\n !document.querySelector(\"[\" + BOX_SIZE_ATTR + '=\"true\"]') &&\n !document.querySelector(\"[\" + ROTATION_ATTR + '=\"true\"]') &&\n !document.querySelector(\"[\" + MOTION_ATTR + \"]\")\n )\n return;\n\n const splitTopLevelWhitespace = (value: string): string[] => {\n const parts: string[] = [];\n let depth = 0;\n let current = \"\";\n for (const char of value.trim()) {\n if (char === \"(\") depth += 1;\n if (char === \")\") depth = Math.max(0, depth - 1);\n if (/\\s/.test(char) && depth === 0) {\n if (current) parts.push(current);\n current = \"\";\n } else {\n current += char;\n }\n }\n if (current) parts.push(current);\n return parts;\n };\n\n const composeTranslate = (element: HTMLElement, x: string, y: string): string => {\n const original = element.getAttribute(ORIGINAL_TRANSLATE_ATTR)?.trim();\n if (!original || original === \"none\") return x + \" \" + y;\n const parts = splitTopLevelWhitespace(original);\n if (parts.length === 1) return \"calc(\" + parts[0] + \" + \" + x + \") \" + y;\n if (parts.length >= 2) {\n const z = parts.length >= 3 ? \" \" + parts[2] : \"\";\n return \"calc(\" + parts[0] + \" + \" + x + \") calc(\" + parts[1] + \" + \" + y + \")\" + z;\n }\n return x + \" \" + y;\n };\n\n const isSimpleRotateAngle = (value: string): boolean =>\n /^-?(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:deg|rad|turn|grad)$/.test(value.trim());\n\n const composeRotation = (element: HTMLElement, rotationValue: string): string => {\n const original = element.getAttribute(ORIGINAL_ROTATE_ATTR)?.trim();\n if (!original || original === \"none\" || !isSimpleRotateAngle(original)) return rotationValue;\n return \"calc(\" + original + \" + \" + rotationValue + \")\";\n };\n\n let lastSeekTime = 0;\n let cachedMotionKey = \"\";\n\n const finiteNum = (v: unknown): number | null =>\n typeof v === \"number\" && Number.isFinite(v) ? v : null;\n\n const computeMotionKey = (motionEls: NodeListOf<Element>): string => {\n let key = \"\";\n for (let i = 0; i < motionEls.length; i++) {\n const json = (motionEls[i] as HTMLElement).getAttribute?.(MOTION_ATTR);\n if (json) key += (key ? \"\\n\" : \"\") + json;\n }\n return key;\n };\n\n const reapplyMotionTimeline = (): void => {\n const motionEls = document.querySelectorAll(\"[\" + MOTION_ATTR + \"]\");\n if (motionEls.length === 0) {\n cachedMotionKey = \"\";\n return;\n }\n const win = window as Window & {\n gsap?: {\n timeline?: (opts: Record<string, unknown>) => Record<string, unknown>;\n set?: (el: HTMLElement, vars: Record<string, unknown>) => void;\n registerPlugin?: (plugin: unknown) => void;\n };\n CustomEase?: { create?: (id: string, data: string) => void };\n __timelines?: Record<string, Record<string, unknown>>;\n };\n const gsap = win.gsap;\n if (!gsap || typeof gsap.timeline !== \"function\") return;\n win.__timelines = win.__timelines || {};\n\n // Cache the timeline keyed by the concatenated motion JSON strings.\n // On each seek, if the key hasn't changed, just seek the existing timeline\n // instead of rebuilding it (avoids kill+recreate on every frame).\n const motionKey = computeMotionKey(motionEls);\n const existing = win.__timelines[MOTION_TL_KEY];\n if (\n motionKey &&\n motionKey === cachedMotionKey &&\n existing &&\n typeof existing.totalTime === \"function\"\n ) {\n (existing.totalTime as (t: number, s: boolean) => void)(lastSeekTime, false);\n return;\n }\n\n if (existing && typeof existing.kill === \"function\") (existing.kill as () => void)();\n const tl = gsap.timeline({ paused: true, defaults: { overwrite: \"auto\" } });\n const fromTo = tl.fromTo as (\n el: HTMLElement,\n from: Record<string, unknown>,\n to: Record<string, unknown>,\n pos: number,\n ) => void;\n if (typeof fromTo !== \"function\") return;\n let applied = 0;\n for (let i = 0; i < motionEls.length; i++) {\n const el = motionEls[i] as HTMLElement;\n if (!(el instanceof HTMLElement)) continue;\n const json = el.getAttribute(MOTION_ATTR);\n if (!json) continue;\n try {\n const m = JSON.parse(json) as Record<string, unknown>;\n const start = finiteNum(m.start);\n const duration = finiteNum(m.duration);\n if (start == null || duration == null || duration <= 0) continue;\n const ease = typeof m.ease === \"string\" ? m.ease : \"none\";\n const from = (m.from && typeof m.from === \"object\" ? m.from : {}) as Record<\n string,\n unknown\n >;\n const to = (m.to && typeof m.to === \"object\" ? m.to : {}) as Record<string, unknown>;\n const customEase = m.customEase as { id?: string; data?: string } | null | undefined;\n let resolvedEase = ease;\n if (customEase?.id && customEase?.data && win.CustomEase?.create) {\n try {\n gsap.registerPlugin?.(win.CustomEase);\n win.CustomEase.create(customEase.id, customEase.data);\n resolvedEase = customEase.id;\n } catch {\n /* use default ease */\n }\n }\n fromTo.call(\n tl,\n el,\n { ...from },\n { ...to, duration, ease: resolvedEase, overwrite: \"auto\", immediateRender: false },\n start,\n );\n applied += 1;\n } catch {\n /* malformed JSON — skip */\n }\n }\n if (applied === 0) {\n cachedMotionKey = \"\";\n if (typeof (tl as { kill?: () => void }).kill === \"function\")\n (tl as { kill: () => void }).kill();\n return;\n }\n cachedMotionKey = motionKey;\n win.__timelines[MOTION_TL_KEY] = tl;\n if (typeof tl.pause === \"function\") (tl.pause as () => void)();\n if (typeof tl.totalTime === \"function\")\n (tl.totalTime as (t: number, s: boolean) => void)(lastSeekTime, false);\n };\n\n const stripGsapTranslateFromTransform = (el: HTMLElement): void => {\n const transform = el.style.getPropertyValue(\"transform\");\n if (!transform || transform === \"none\") return;\n const win = el.ownerDocument.defaultView as (Window & typeof globalThis) | null;\n const MatrixCtor = (win as unknown as { DOMMatrix?: typeof DOMMatrix })?.DOMMatrix;\n if (!MatrixCtor) return;\n try {\n const m = new MatrixCtor(transform);\n if (m.m41 === 0 && m.m42 === 0) return;\n m.m41 = 0;\n m.m42 = 0;\n if (m.is2D && m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1) {\n el.style.removeProperty(\"transform\");\n } else {\n el.style.setProperty(\"transform\", m.toString());\n }\n } catch {\n /* non-parseable transform — leave as-is */\n }\n };\n\n const reapplyAll = (): void => {\n const offsetEls = document.querySelectorAll(\"[\" + PATH_OFFSET_ATTR + '=\"true\"]');\n for (let i = 0; i < offsetEls.length; i++) {\n const el = offsetEls[i] as HTMLElement;\n if (!(el instanceof HTMLElement)) continue;\n const x = el.style.getPropertyValue(OFFSET_X_PROP);\n const y = el.style.getPropertyValue(OFFSET_Y_PROP);\n if (x || y) {\n el.style.setProperty(\n \"translate\",\n composeTranslate(\n el,\n \"var(\" + OFFSET_X_PROP + \", 0px)\",\n \"var(\" + OFFSET_Y_PROP + \", 0px)\",\n ),\n );\n stripGsapTranslateFromTransform(el);\n }\n }\n const boxSizeEls = document.querySelectorAll(\"[\" + BOX_SIZE_ATTR + '=\"true\"]');\n for (let i = 0; i < boxSizeEls.length; i++) {\n const el = boxSizeEls[i] as HTMLElement;\n if (!(el instanceof HTMLElement)) continue;\n const w = el.style.getPropertyValue(WIDTH_PROP);\n const h = el.style.getPropertyValue(HEIGHT_PROP);\n if (w) el.style.setProperty(\"width\", w);\n if (h) el.style.setProperty(\"height\", h);\n }\n const rotEls = document.querySelectorAll(\"[\" + ROTATION_ATTR + '=\"true\"]');\n for (let i = 0; i < rotEls.length; i++) {\n const el = rotEls[i] as HTMLElement;\n if (!(el instanceof HTMLElement)) continue;\n const rot = el.style.getPropertyValue(ROTATION_PROP);\n if (rot) {\n el.style.setProperty(\"rotate\", composeRotation(el, \"var(\" + ROTATION_PROP + \", 0deg)\"));\n stripGsapTranslateFromTransform(el);\n }\n }\n reapplyMotionTimeline();\n };\n\n const runtimeWindow = window as Window & {\n __hf?: Record<string, unknown>;\n __player?: Record<string, unknown>;\n };\n\n const isWrapped = (fn: (time: number) => unknown): boolean =>\n Boolean((fn as unknown as Record<string, unknown>)[WRAPPED_PROP]);\n\n const markWrapped = (fn: (time: number) => unknown): void => {\n try {\n Object.defineProperty(fn, WRAPPED_PROP, {\n configurable: false,\n enumerable: false,\n value: true,\n });\n } catch {\n try {\n (fn as unknown as Record<string, unknown>)[WRAPPED_PROP] = true;\n } catch {\n /* ignore */\n }\n }\n };\n\n const wrapFn = (get: () => unknown, set: (fn: (time: number) => unknown) => void): boolean => {\n const fn = get();\n if (typeof fn !== \"function\") return false;\n const seek = fn as (time: number) => unknown;\n if (isWrapped(seek)) {\n reapplyAll();\n return true;\n }\n const wrapped = function (this: unknown, time: number): unknown {\n lastSeekTime = typeof time === \"number\" && Number.isFinite(time) ? Math.max(0, time) : 0;\n const result = seek.call(this, time);\n reapplyAll();\n return result;\n };\n markWrapped(wrapped);\n set(wrapped);\n reapplyAll();\n return true;\n };\n\n const wrapSeekFunctions = (): boolean => {\n const a = wrapFn(\n () => runtimeWindow.__hf?.[\"seek\"],\n (fn) => {\n if (runtimeWindow.__hf) runtimeWindow.__hf[\"seek\"] = fn;\n },\n );\n const b = wrapFn(\n () => runtimeWindow.__player?.[\"renderSeek\"],\n (fn) => {\n if (runtimeWindow.__player) runtimeWindow.__player[\"renderSeek\"] = fn;\n },\n );\n return a || b;\n };\n\n const installSeekTrap = (\n obj: Record<string, unknown> | undefined,\n key: string,\n getter: () => unknown,\n setter: (fn: (time: number) => unknown) => void,\n ): void => {\n if (!obj) return;\n try {\n let current = obj[key];\n Object.defineProperty(obj, key, {\n configurable: true,\n enumerable: true,\n get() {\n return current;\n },\n set(value: unknown) {\n current = value;\n if (typeof value === \"function\" && !isWrapped(value as (time: number) => unknown)) {\n wrapFn(getter, setter);\n }\n },\n });\n } catch {\n /* non-configurable — fall back to polling */\n }\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", () => reapplyAll(), { once: true });\n } else {\n reapplyAll();\n }\n\n wrapSeekFunctions();\n installSeekTrap(\n runtimeWindow.__hf,\n \"seek\",\n () => runtimeWindow.__hf?.[\"seek\"],\n (fn) => {\n if (runtimeWindow.__hf) runtimeWindow.__hf[\"seek\"] = fn;\n },\n );\n installSeekTrap(\n runtimeWindow.__player as Record<string, unknown> | undefined,\n \"renderSeek\",\n () => runtimeWindow.__player?.[\"renderSeek\"],\n (fn) => {\n if (runtimeWindow.__player) runtimeWindow.__player[\"renderSeek\"] = fn;\n },\n );\n let remaining = 120;\n const interval = setInterval(() => {\n wrapSeekFunctions();\n remaining -= 1;\n if (remaining <= 0) clearInterval(interval);\n }, 50);\n}\n\nfunction studioManualEditsRenderRuntime(\n manifestContent: string,\n activeCompositionPath: string | null,\n): void {\n const OFFSET_X_PROP = \"--hf-studio-offset-x\";\n const OFFSET_Y_PROP = \"--hf-studio-offset-y\";\n const WIDTH_PROP = \"--hf-studio-width\";\n const HEIGHT_PROP = \"--hf-studio-height\";\n const ROTATION_PROP = \"--hf-studio-rotation\";\n const PATH_OFFSET_ATTR = \"data-hf-studio-path-offset\";\n const BOX_SIZE_ATTR = \"data-hf-studio-box-size\";\n const ROTATION_ATTR = \"data-hf-studio-rotation\";\n const ORIGINAL_TRANSLATE_ATTR = \"data-hf-studio-original-translate\";\n const ORIGINAL_ROTATE_ATTR = \"data-hf-studio-original-rotate\";\n const WRAPPED_SEEK_PROP = \"__hfStudioManualEditsWrapped\";\n const ROTATION_TRANSFORM_ORIGIN = \"center center\";\n\n const finiteNumber = (value: unknown): number | null =>\n typeof value === \"number\" && Number.isFinite(value) ? value : null;\n\n const objectRecord = (value: unknown): Record<string, unknown> | null =>\n value && typeof value === \"object\" ? (value as Record<string, unknown>) : null;\n\n const runtimeWindow = window as Window & {\n __hf?: { seek?: (time: number) => unknown };\n __hfStudioManualEditsApply?: () => number;\n __player?: { renderSeek?: (time: number) => unknown };\n };\n\n const parsedManifest = (() => {\n try {\n return objectRecord(JSON.parse(manifestContent));\n } catch {\n return null;\n }\n })();\n const manifestEdits = Array.isArray(parsedManifest?.edits) ? parsedManifest.edits : [];\n if (manifestEdits.length === 0) return;\n\n const sourceFileForElement = (element: HTMLElement): string => {\n let current: HTMLElement | null = element;\n while (current) {\n const sourceFile =\n current.getAttribute(\"data-composition-file\") ??\n current.getAttribute(\"data-composition-src\");\n if (sourceFile) return sourceFile;\n current = current.parentElement;\n }\n return activeCompositionPath ?? \"index.html\";\n };\n\n const elementMatchesSourceFile = (element: HTMLElement, sourceFile: string): boolean =>\n sourceFileForElement(element) === sourceFile;\n\n const styleUsesStudioOffset = (value: string): boolean =>\n value.includes(OFFSET_X_PROP) || value.includes(OFFSET_Y_PROP);\n\n const styleUsesStudioRotation = (value: string): boolean => value.includes(ROTATION_PROP);\n\n const splitTopLevelWhitespace = (value: string): string[] => {\n const parts: string[] = [];\n let depth = 0;\n let current = \"\";\n for (const char of value.trim()) {\n if (char === \"(\") depth += 1;\n if (char === \")\") depth = Math.max(0, depth - 1);\n if (/\\s/.test(char) && depth === 0) {\n if (current) parts.push(current);\n current = \"\";\n } else {\n current += char;\n }\n }\n if (current) parts.push(current);\n return parts;\n };\n\n const composeTranslate = (element: HTMLElement, x: string, y: string): string => {\n const original = element.getAttribute(ORIGINAL_TRANSLATE_ATTR)?.trim();\n if (!original || original === \"none\") return `${x} ${y}`;\n\n const parts = splitTopLevelWhitespace(original);\n if (parts.length === 1) return `calc(${parts[0]} + ${x}) ${y}`;\n if (parts.length === 2) return `calc(${parts[0]} + ${x}) calc(${parts[1]} + ${y})`;\n if (parts.length === 3) {\n return `calc(${parts[0]} + ${x}) calc(${parts[1]} + ${y}) ${parts[2]}`;\n }\n return `${x} ${y}`;\n };\n\n const readStyleOrComputed = (element: HTMLElement, property: string): string => {\n try {\n return (\n element.style.getPropertyValue(property) ||\n getComputedStyle(element).getPropertyValue(property)\n );\n } catch {\n return element.style.getPropertyValue(property);\n }\n };\n\n const readTransformLonghandBase = (\n element: HTMLElement,\n property: \"translate\" | \"rotate\",\n ): string => {\n const value = readStyleOrComputed(element, property).trim();\n return value === \"none\" ? \"\" : value;\n };\n\n const preparePathOffsetBase = (element: HTMLElement): void => {\n const currentTranslate = readTransformLonghandBase(element, \"translate\");\n const hasMarker = element.hasAttribute(PATH_OFFSET_ATTR);\n const wasResetByAnimation = !styleUsesStudioOffset(currentTranslate);\n if (!hasMarker) {\n element.setAttribute(ORIGINAL_TRANSLATE_ATTR, wasResetByAnimation ? currentTranslate : \"\");\n } else if (wasResetByAnimation) {\n element.setAttribute(ORIGINAL_TRANSLATE_ATTR, currentTranslate);\n }\n };\n\n const prepareRotationBase = (element: HTMLElement): void => {\n const currentRotate = readTransformLonghandBase(element, \"rotate\");\n const hasMarker = element.hasAttribute(ROTATION_ATTR);\n const wasResetByAnimation = !styleUsesStudioRotation(currentRotate);\n if (!hasMarker) {\n element.setAttribute(ORIGINAL_ROTATE_ATTR, wasResetByAnimation ? currentRotate : \"\");\n } else if (wasResetByAnimation) {\n element.setAttribute(ORIGINAL_ROTATE_ATTR, currentRotate);\n }\n };\n\n const querySelectorCandidates = (selector: string): HTMLElement[] => {\n const isCandidate = (element: Element): element is HTMLElement =>\n element instanceof HTMLElement;\n\n const className = selector.match(/^\\.([A-Za-z0-9_-]+)$/)?.[1];\n if (className) {\n return Array.from(document.getElementsByTagName(\"*\")).filter(\n (element): element is HTMLElement =>\n isCandidate(element) && element.classList.contains(className),\n );\n }\n\n if (/^[A-Za-z][A-Za-z0-9-]*$/.test(selector)) {\n return Array.from(document.getElementsByTagName(selector)).filter(isCandidate);\n }\n\n return Array.from(document.querySelectorAll(selector)).filter(isCandidate);\n };\n\n const resolveTarget = (edit: Record<string, unknown>): HTMLElement | null => {\n const targetRecord = objectRecord(edit.target);\n if (!targetRecord) return null;\n\n const sourceFile = typeof targetRecord.sourceFile === \"string\" ? targetRecord.sourceFile : \"\";\n if (!sourceFile) return null;\n\n const id = typeof targetRecord.id === \"string\" ? targetRecord.id : \"\";\n if (id) {\n const byId = document.getElementById(id);\n if (byId instanceof HTMLElement && elementMatchesSourceFile(byId, sourceFile)) return byId;\n\n const matchesById = [\n document.documentElement,\n ...Array.from(document.getElementsByTagName(\"*\")),\n ].filter(\n (element): element is HTMLElement =>\n element instanceof HTMLElement &&\n element.id === id &&\n elementMatchesSourceFile(element, sourceFile),\n );\n if (matchesById[0]) return matchesById[0];\n }\n\n const selector = typeof targetRecord.selector === \"string\" ? targetRecord.selector : \"\";\n if (!selector) return null;\n\n try {\n const matches = querySelectorCandidates(selector).filter((element) =>\n elementMatchesSourceFile(element, sourceFile),\n );\n const selectorIndex = finiteNumber(targetRecord.selectorIndex) ?? 0;\n return matches[Math.max(0, Math.floor(selectorIndex))] ?? null;\n } catch {\n return null;\n }\n };\n\n const roundRotationAngle = (angle: number): number => Math.round(angle * 10) / 10;\n\n const isSimpleRotateAngle = (value: string): boolean =>\n /^-?(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:deg|rad|turn|grad)$/.test(value.trim());\n\n const composeRotation = (element: HTMLElement, rotationValue: string): string => {\n const original = element.getAttribute(ORIGINAL_ROTATE_ATTR)?.trim();\n if (!original || original === \"none\" || !isSimpleRotateAngle(original)) {\n return rotationValue;\n }\n return `calc(${original} + ${rotationValue})`;\n };\n\n const applyPathOffset = (element: HTMLElement, edit: Record<string, unknown>): void => {\n const x = finiteNumber(edit.x);\n const y = finiteNumber(edit.y);\n if (x == null || y == null) return;\n preparePathOffsetBase(element);\n element.setAttribute(PATH_OFFSET_ATTR, \"true\");\n element.style.setProperty(OFFSET_X_PROP, `${Math.round(x)}px`);\n element.style.setProperty(OFFSET_Y_PROP, `${Math.round(y)}px`);\n element.style.setProperty(\n \"translate\",\n composeTranslate(element, `var(${OFFSET_X_PROP}, 0px)`, `var(${OFFSET_Y_PROP}, 0px)`),\n );\n };\n\n const readParentFlexBasisPixels = (\n element: HTMLElement,\n size: { width: number; height: number },\n ): number | null => {\n const parent = element.parentElement;\n if (!parent) return null;\n const styles = getComputedStyle(parent);\n if (styles.display !== \"flex\" && styles.display !== \"inline-flex\") return null;\n return Math.round(\n Math.max(1, styles.flexDirection.startsWith(\"column\") ? size.height : size.width),\n );\n };\n\n const applyBoxSize = (element: HTMLElement, edit: Record<string, unknown>): void => {\n const width = finiteNumber(edit.width);\n const height = finiteNumber(edit.height);\n if (width == null || height == null || width <= 0 || height <= 0) return;\n\n const rounded = {\n width: Math.round(Math.max(1, width)),\n height: Math.round(Math.max(1, height)),\n };\n element.setAttribute(BOX_SIZE_ATTR, \"true\");\n element.style.setProperty(WIDTH_PROP, `${rounded.width}px`);\n element.style.setProperty(HEIGHT_PROP, `${rounded.height}px`);\n element.style.setProperty(\"box-sizing\", \"border-box\");\n element.style.setProperty(\"width\", `${rounded.width}px`);\n element.style.setProperty(\"height\", `${rounded.height}px`);\n element.style.setProperty(\"min-width\", \"0px\");\n element.style.setProperty(\"min-height\", \"0px\");\n element.style.setProperty(\"max-width\", \"none\");\n element.style.setProperty(\"max-height\", \"none\");\n\n const flexBasis = readParentFlexBasisPixels(element, rounded);\n if (flexBasis != null) {\n element.style.setProperty(\"flex-basis\", `${flexBasis}px`);\n element.style.setProperty(\"flex-grow\", \"0\");\n element.style.setProperty(\"flex-shrink\", \"0\");\n }\n if (getComputedStyle(element).display === \"inline\") {\n element.style.setProperty(\"display\", \"inline-block\");\n }\n };\n\n const applyRotation = (element: HTMLElement, edit: Record<string, unknown>): void => {\n const angle = finiteNumber(edit.angle);\n if (angle == null) return;\n prepareRotationBase(element);\n element.setAttribute(ROTATION_ATTR, \"true\");\n element.style.setProperty(ROTATION_PROP, `${roundRotationAngle(angle)}deg`);\n element.style.setProperty(\"transform-origin\", ROTATION_TRANSFORM_ORIGIN);\n element.style.setProperty(\"rotate\", composeRotation(element, `var(${ROTATION_PROP}, 0deg)`));\n };\n\n const applyManifest = (): number => {\n let applied = 0;\n for (const edit of manifestEdits) {\n const editRecord = objectRecord(edit);\n if (!editRecord) continue;\n const element = resolveTarget(editRecord);\n if (!element) continue;\n if (editRecord.kind === \"path-offset\") applyPathOffset(element, editRecord);\n if (editRecord.kind === \"box-size\") applyBoxSize(element, editRecord);\n if (editRecord.kind === \"rotation\") applyRotation(element, editRecord);\n applied += 1;\n }\n return applied;\n };\n runtimeWindow.__hfStudioManualEditsApply = applyManifest;\n\n const markWrapped = (fn: (time: number) => unknown): void => {\n try {\n Object.defineProperty(fn, WRAPPED_SEEK_PROP, {\n configurable: false,\n enumerable: false,\n value: true,\n });\n } catch {\n try {\n (fn as unknown as Record<string, unknown>)[WRAPPED_SEEK_PROP] = true;\n } catch {\n // Ignore non-extensible functions.\n }\n }\n };\n\n const isWrapped = (fn: (time: number) => unknown): boolean =>\n Boolean((fn as unknown as Record<string, unknown>)[WRAPPED_SEEK_PROP]);\n\n const wrapFunction = (\n get: () => ((time: number) => unknown) | undefined,\n set: (fn: (time: number) => unknown) => void,\n ): boolean => {\n const fn = get();\n if (!fn) return false;\n const seek = fn as (time: number) => unknown;\n if (isWrapped(seek)) {\n applyManifest();\n return true;\n }\n\n const wrappedSeek = function (this: unknown, time: number): unknown {\n const result = seek.call(this, time);\n applyManifest();\n return result;\n };\n markWrapped(wrappedSeek);\n set(wrappedSeek);\n applyManifest();\n return true;\n };\n\n const wrapSeekFunctions = (): boolean => {\n const wrappedHfSeek = wrapFunction(\n () => runtimeWindow.__hf?.seek,\n (fn) => {\n if (runtimeWindow.__hf) runtimeWindow.__hf.seek = fn;\n },\n );\n const wrappedPlayerRenderSeek = wrapFunction(\n () => runtimeWindow.__player?.renderSeek,\n (fn) => {\n if (runtimeWindow.__player) runtimeWindow.__player.renderSeek = fn;\n },\n );\n return wrappedHfSeek || wrappedPlayerRenderSeek;\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", () => applyManifest(), { once: true });\n } else {\n applyManifest();\n }\n\n wrapSeekFunctions();\n let remainingSeekWrapAttempts = 120;\n const seekWrapInterval = setInterval(() => {\n wrapSeekFunctions();\n remainingSeekWrapAttempts -= 1;\n if (remainingSeekWrapAttempts <= 0) clearInterval(seekWrapInterval);\n }, 50);\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Hono } from \"hono\";\nimport type { StudioApiAdapter } from \"../types.js\";\nimport { decodeAudioPeaks, buildWaveformCacheKey } from \"../helpers/waveform.js\";\n\nexport function registerWaveformRoutes(api: Hono, adapter: StudioApiAdapter): void {\n api.get(\"/projects/:id/waveform/*\", async (c) => {\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"not found\" }, 404);\n\n const assetPath = decodeURIComponent(\n c.req.path.replace(`/projects/${project.id}/waveform/`, \"\").split(\"?\")[0] ?? \"\",\n );\n const audioPath = join(project.dir, assetPath);\n if (!existsSync(audioPath)) return c.json({ error: \"file not found\" }, 404);\n\n const cacheDir = join(project.dir, \".waveform-cache\");\n const cachePath = join(cacheDir, buildWaveformCacheKey(assetPath));\n\n if (existsSync(cachePath)) {\n try {\n const peaks = JSON.parse(readFileSync(cachePath, \"utf-8\")) as number[];\n return c.json({ peaks });\n } catch {\n // corrupt cache — regenerate\n }\n }\n\n let peaks: number[];\n try {\n peaks = await decodeAudioPeaks(audioPath);\n } catch {\n return c.json({ error: \"failed to decode audio\" }, 500);\n }\n\n try {\n mkdirSync(cacheDir, { recursive: true });\n writeFileSync(cachePath, JSON.stringify(peaks));\n } catch {\n // cache write failure is non-fatal\n }\n\n return c.json({ peaks });\n });\n}\n","import { closeSync, constants, fstatSync, openSync, readSync } from \"node:fs\";\nimport type { Hono } from \"hono\";\nimport {\n collectFontFileEntries,\n fontDirectories,\n getSystemProfilerFamilies,\n locateSystemFont,\n SYSTEM_FONT_SIZE_LIMIT,\n} from \"@hyperframes/core/fonts/system-locator\";\n\nconst MAX_FONT_RESULTS = 2000;\nconst GOOGLE_FONTS_METADATA_URL = \"https://fonts.google.com/metadata/fonts\";\nconst GOOGLE_FONTS_FETCH_TIMEOUT_MS = 3000;\nlet cachedFonts: string[] | null = null;\nlet cachedGoogleFonts: string[] | null = null;\n\nconst GOOGLE_FONT_FALLBACKS = [\n \"Inter\",\n \"Roboto\",\n \"Open Sans\",\n \"Montserrat\",\n \"Poppins\",\n \"Lato\",\n \"Oswald\",\n \"Raleway\",\n \"Nunito\",\n \"Playfair Display\",\n \"Merriweather\",\n \"Source Sans 3\",\n \"Source Serif 4\",\n \"Source Code Pro\",\n \"DM Sans\",\n \"Space Grotesk\",\n \"Space Mono\",\n \"Bebas Neue\",\n \"Outfit\",\n \"JetBrains Mono\",\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction collectFontsFromDir(dir: string): string[] {\n return collectFontFileEntries(dir).map((e) => e.family);\n}\n\nfunction listInstalledFontFamilies(): string[] {\n if (cachedFonts) return cachedFonts;\n const families = new Set<string>();\n\n for (const family of getSystemProfilerFamilies()) {\n families.add(family);\n if (families.size >= MAX_FONT_RESULTS) break;\n }\n\n for (const dir of fontDirectories()) {\n for (const family of collectFontsFromDir(dir)) {\n families.add(family);\n if (families.size >= MAX_FONT_RESULTS) break;\n }\n if (families.size >= MAX_FONT_RESULTS) break;\n }\n\n cachedFonts = Array.from(families).sort((a, b) => a.localeCompare(b));\n return cachedFonts;\n}\n\nfunction parseGoogleFontMetadata(value: unknown): string[] {\n if (!isRecord(value) || !Array.isArray(value.familyMetadataList)) return [];\n const families: string[] = [];\n for (const entry of value.familyMetadataList) {\n if (!isRecord(entry) || typeof entry.family !== \"string\") continue;\n families.push(entry.family);\n }\n return families;\n}\n\nfunction stripGoogleJsonGuard(raw: string): string {\n const prefix = \")]}'\";\n if (!raw.startsWith(prefix)) return raw;\n\n let index = prefix.length;\n while (\n index < raw.length &&\n (raw[index] === \" \" ||\n raw[index] === \"\\n\" ||\n raw[index] === \"\\r\" ||\n raw[index] === \"\\t\" ||\n raw[index] === \"\\f\")\n ) {\n index += 1;\n }\n\n return raw.slice(index);\n}\n\nasync function listGoogleFontFamilies(): Promise<string[]> {\n if (cachedGoogleFonts) return cachedGoogleFonts;\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), GOOGLE_FONTS_FETCH_TIMEOUT_MS);\n\n try {\n const response = await fetch(GOOGLE_FONTS_METADATA_URL, { signal: controller.signal });\n if (!response.ok) {\n cachedGoogleFonts = GOOGLE_FONT_FALLBACKS;\n return cachedGoogleFonts;\n }\n const raw = await response.text();\n const jsonText = stripGoogleJsonGuard(raw);\n const families = parseGoogleFontMetadata(JSON.parse(jsonText));\n cachedGoogleFonts = families.length > 0 ? families : GOOGLE_FONT_FALLBACKS;\n } catch {\n cachedGoogleFonts = GOOGLE_FONT_FALLBACKS;\n } finally {\n clearTimeout(timer);\n }\n\n return cachedGoogleFonts;\n}\n\nexport function registerFontRoutes(api: Hono): void {\n api.get(\"/fonts\", (c) => c.json({ fonts: listInstalledFontFamilies() }));\n api.get(\"/fonts/google\", async (c) => c.json({ fonts: await listGoogleFontFamilies() }));\n\n // fallow-ignore-next-line complexity\n api.get(\"/fonts/file\", (c) => {\n const family = c.req.query(\"family\");\n if (!family) return c.json({ error: \"family parameter required\" }, 400);\n\n const located = locateSystemFont(family);\n if (!located) return c.json({ error: \"font not found\" }, 404);\n\n let fd: number;\n try {\n fd = openSync(located.path, constants.O_RDONLY | constants.O_NOFOLLOW);\n } catch {\n return c.json({ error: \"font file not accessible\" }, 404);\n }\n try {\n const stat = fstatSync(fd);\n if (stat.size > SYSTEM_FONT_SIZE_LIMIT) {\n return c.json({ error: \"font file too large\" }, 413);\n }\n const buffer = Buffer.alloc(stat.size);\n readSync(fd, buffer, 0, stat.size, 0);\n const mimeType =\n located.format === \"otf\"\n ? \"font/otf\"\n : located.format === \"woff2\"\n ? \"font/woff2\"\n : located.format === \"woff\"\n ? \"font/woff\"\n : located.format === \"ttc\"\n ? \"font/collection\"\n : \"font/ttf\";\n\n const fileName = `${family.replace(/[^a-zA-Z0-9 -]/g, \"\")}.${located.format}`;\n return new Response(buffer, {\n headers: {\n \"Content-Type\": mimeType,\n \"Content-Disposition\": `attachment; filename=\"${fileName}\"`,\n },\n });\n } catch {\n return c.json({ error: \"failed to read font file\" }, 500);\n } finally {\n closeSync(fd);\n }\n });\n}\n","import type { Hono } from \"hono\";\nimport type { StudioApiAdapter } from \"../types.js\";\n\nexport function registerRegistryRoutes(api: Hono, adapter: StudioApiAdapter): void {\n api.get(\"/registry/blocks\", async (c) => {\n if (!adapter.listRegistryCatalog) {\n return c.json({ error: \"Registry not available\" }, 501);\n }\n const items = await adapter.listRegistryCatalog();\n return c.json(items);\n });\n\n // fallow-ignore-next-line complexity\n api.post(\"/projects/:id/registry/install\", async (c) => {\n if (!adapter.installRegistryBlock) {\n return c.json({ error: \"Registry install not available\" }, 501);\n }\n const project = await adapter.resolveProject(c.req.param(\"id\"));\n if (!project) return c.json({ error: \"Project not found\" }, 404);\n\n const body = await c.req.json<{ blockName?: string }>().catch(() => null);\n if (!body?.blockName) {\n return c.json({ error: \"blockName is required\" }, 400);\n }\n\n try {\n const result = await adapter.installRegistryBlock({ project, blockName: body.blockName });\n return c.json(result);\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Install failed\";\n return c.json({ error: message }, 500);\n }\n });\n}\n","export interface ScreenshotClip {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport function getElementScreenshotClip(\n selector: string,\n selectorIndex?: number,\n): ScreenshotClip | undefined {\n const matches = Array.from(document.querySelectorAll(selector)).filter(\n (el): el is HTMLElement => el instanceof HTMLElement,\n );\n const safeIndex = Math.max(0, Math.min(matches.length - 1, Math.floor(selectorIndex ?? 0)));\n const el = matches[safeIndex] ?? null;\n if (!(el instanceof HTMLElement)) return undefined;\n const rect = el.getBoundingClientRect();\n if (rect.width < 4 || rect.height < 4) return undefined;\n const pad = 8;\n const x = Math.max(0, rect.left - pad);\n const y = Math.max(0, rect.top - pad);\n const maxWidth = window.innerWidth - x;\n const maxHeight = window.innerHeight - y;\n return {\n x,\n y,\n width: Math.max(1, Math.min(rect.width + pad * 2, maxWidth)),\n height: Math.max(1, Math.min(rect.height + pad * 2, maxHeight)),\n };\n}\n"],"mappings":"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","names":["join","join","existsSync","readFileSync","writeFileSync","mkdirSync","unlinkSync","rmSync","readdirSync","resolve","join","existsSync","join","writeFileSync","join","mkdirSync","readdirSync","readFileSync","writeFileSync","Buffer","join","Buffer","readFileSync","join","mkdirSync","writeFileSync","readdirSync","document","parseHTML","existsSync","writeFileSync","mkdirSync","resolve","readdirSync","join","readFileSync","document","updateAnimationInScript","addAnimationToScript","removeAnimationFromScript","addKeyframeToScript","removeKeyframeFromScript","updateKeyframeInScript","removeAllKeyframesFromScript","unrollDynamicAnimations","setArcPathInScript","updateArcSegmentInScript","removeArcPathFromScript","addAnimationWithKeyframesToScript","splitAnimationsInScript","shiftPositionsInScript","scalePositionsInScript","rmSync","unlinkSync","existsSync","readFileSync","statSync","join","stripEmbeddedRuntimeScripts","existsSync","readFileSync","join","parseHTML","readFileSync","readdirSync","relative","resolve","isHTMLElement","ensureHfIds","readFileSync","writeFileSync","join","existsSync","readFileSync","stripEmbeddedRuntimeScripts","ensureHfIds","statSync","readFileSync","join","readFileSync","join","existsSync","readFileSync","mkdirSync","unlinkSync","readdirSync","statSync","join","existsSync","mkdirSync","join","readFileSync","unlinkSync","readdirSync","statSync","existsSync","readFileSync","writeFileSync","mkdirSync","statSync","join","createHash","join","existsSync","statSync","readFileSync","createHash","mkdirSync","writeFileSync","existsSync","readFileSync","writeFileSync","mkdirSync","join","join","existsSync","peaks","readFileSync","mkdirSync","writeFileSync","el"]}