{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "sponsor-orcdev",
  "title": "remocn ✕ OrcDev — New sponsor",
  "description": "remocn demo composition \"remocn ✕ OrcDev — New sponsor\" — installs the full Remotion composition. Generated with AI from the prompt in demos/sponsor-orcdev/prompt.md.",
  "dependencies": [
    "@paper-design/shaders-react",
    "@remotion/fonts",
    "@remotion/gif",
    "@remotion/google-fonts",
    "@remotion/transitions",
    "remotion"
  ],
  "registryDependencies": [
    "https://remocn.dev/r/dither-dissolve.json",
    "https://remocn.dev/r/shader-dithering.json"
  ],
  "files": [
    {
      "path": "src/demos/sponsor-orcdev/index.tsx",
      "content": "import React, { useState } from \"react\";\nimport { AbsoluteFill, Img, continueRender, delayRender, interpolate, useCurrentFrame } from \"remotion\";\nimport { demoAsset } from \"@/lib/demo-assets\";\nimport { TransitionSeries, linearTiming } from \"@remotion/transitions\";\nimport { Gif } from \"@remotion/gif\";\nimport { loadFont as loadPixel } from \"@remotion/fonts\";\nimport { loadFont as loadSans } from \"@remotion/google-fonts/Geist\";\n\nimport { ShaderDithering } from \"@/components/remocn/shader-dithering\";\nimport { ditherDissolve } from \"@/components/remocn/dither-dissolve\";\n\n// 8bitcn speaks shadcn's language — Geist Sans for the small print…\nconst { fontFamily: SANS_FAMILY } = loadSans(\"normal\", {\n  subsets: [\"latin\"],\n  weights: [\"400\", \"500\"],\n});\n\n// …and Geist Pixel (Square) for everything that shouts. Loaded inside the\n// composition — module-scope loadFont fires its delayRender before any\n// composition is mounted and the render proceeds without the font.\nconst PIXEL_FAMILY = \"Geist Pixel\";\nconst usePixelFont = () => {\n  // Loaded in an effect (module-scope loadFont fires its delayRender before\n  // the composition mounts and dies silently). The composition renders\n  // nothing until the font is in document.fonts, and continueRender waits two\n  // rAF ticks after the state flip so the screenshot never catches the\n  // fallback font mid-swap.\n  const [loaded, setLoaded] = useState(false);\n  React.useEffect(() => {\n    const handle = delayRender(\"geist-pixel\");\n    loadPixel({\n      family: PIXEL_FAMILY,\n      url: demoAsset(\"fonts/GeistPixel-Square.woff2\"),\n    })\n      .catch(() => undefined)\n      .then(() => {\n        setLoaded(true);\n        requestAnimationFrame(() =>\n          requestAnimationFrame(() => continueRender(handle)),\n        );\n      });\n    return () => continueRender(handle);\n  }, []);\n  return loaded;\n};\n\nconst PIXEL = `${PIXEL_FAMILY}, monospace`;\nconst SANS = `${SANS_FAMILY}, -apple-system, BlinkMacSystemFont, sans-serif`;\n\n// orcdev palette — black canvas, the paper.design dithering preset's #008000\n// for the backdrop dots, and the bright orc-skin green sampled straight from\n// the orcdev avatar for the accent.\nconst BG = \"#000000\";\nconst DOT_GREEN = \"#008000\";\nconst ORC_GREEN = \"#8ec71e\";\n// HP-bar damage states — classic health-bar traffic light.\nconst HP_YELLOW = \"#f7d51d\";\nconst HP_RED = \"#e53935\";\nconst INK = \"#fafafa\";\nconst MUTED = \"rgba(250,250,250,0.55)\";\nconst FAINT = \"rgba(250,250,250,0.4)\";\n\nconst clampOpts = {\n  extrapolateLeft: \"clamp\" as const,\n  extrapolateRight: \"clamp\" as const,\n};\n\n// Quantize a 0→1 progress into N sprite poses — the whole video moves on\n// steps, never on smooth glides. That's the 8-bit register.\nconst stepped = (p: number, steps: number) =>\n  Math.round(Math.min(1, Math.max(0, p)) * steps) / steps;\n\nconst stepIn = (frame: number, start: number, dur: number, steps = 4) =>\n  stepped(interpolate(frame, [start, start + dur], [0, 1], clampOpts), steps);\n\n// ---------------------------------------------------------------------------\n// Scene timings (frames @ 30fps). Dither transitions overlap.\n// ---------------------------------------------------------------------------\nconst S_INTRO = 81; //   pixelated orc gif in an 8bit frame\nconst S_HOOK = 78; //    \"Say hello to my new sponsor\", word by word\nconst S_REVEAL = 96; //  avatar + OrcDev typed on + tagline\nconst S_BEATS = 72; //   Build / Break / Conquer hard-cut beats\nconst S_8BIT = 131; //   8bitcn/ui + tagline + HP bar critical hit\nconst S_LOCKUP = 120; // Remocn ✕ OrcDev lockup + orcdev.com\n\nconst T_DD = 24; // dither-dissolve cover\n\nexport const SPONSOR_ORCDEV_DURATION =\n  S_INTRO + S_HOOK + S_REVEAL + S_BEATS + S_8BIT + S_LOCKUP - T_DD * 4;\n\nconst greenDither = () =>\n  ditherDissolve({ colorBack: BG, colorFront: DOT_GREEN, shape: \"simplex\" });\n\n// ---------------------------------------------------------------------------\n// PixelBox — the 8bitcn border: straight bars on every edge, stopped one\n// pixel short of the corners so each corner reads as a stepped notch.\n// ---------------------------------------------------------------------------\nconst PixelBox: React.FC<{\n  children: React.ReactNode;\n  border?: number;\n  color?: string;\n  background?: string;\n}> = ({ children, border = 6, color = INK, background = \"transparent\" }) => {\n  const bar = (pos: React.CSSProperties): React.CSSProperties => ({\n    position: \"absolute\",\n    background: color,\n    ...pos,\n  });\n  return (\n    <div style={{ position: \"relative\", background }}>\n      <div style={bar({ top: 0, left: border, right: border, height: border })} />\n      <div\n        style={bar({ bottom: 0, left: border, right: border, height: border })}\n      />\n      <div style={bar({ left: 0, top: border, bottom: border, width: border })} />\n      <div\n        style={bar({ right: 0, top: border, bottom: border, width: border })}\n      />\n      {children}\n    </div>\n  );\n};\n\n// ===========================================================================\n// Scene 1 — Intro. The orc nod gif, crunched into chunky pixels: the gif\n// renders at quarter resolution and is scaled 4x with pixelated sampling,\n// framed by the 8bitcn border. It snaps in through sprite poses and rides a\n// quantized 2px float.\n// ===========================================================================\nconst GIF_W = 440;\nconst GIF_H = 340;\nconst GIF_K = 5; // pixelation factor\n\nconst IntroScene: React.FC = () => {\n  const frame = useCurrentFrame();\n  const q = stepIn(frame, 2, 16, 4);\n  const scale = 0.7 + 0.3 * q;\n  const float = Math.round(Math.sin(frame / 16) * 3) * 2;\n  return (\n    <AbsoluteFill style={{ alignItems: \"center\", justifyContent: \"center\" }}>\n      <div\n        style={{\n          opacity: q > 0 ? 1 : 0,\n          transform: `translateY(${float}px) scale(${scale})`,\n        }}\n      >\n        <PixelBox border={6} background={BG}>\n          <div\n            style={{\n              width: GIF_W,\n              height: GIF_H,\n              margin: 14,\n              overflow: \"hidden\",\n              display: \"flex\",\n              alignItems: \"center\",\n              justifyContent: \"center\",\n            }}\n          >\n            <Gif\n              src={demoAsset(\"orc.gif\")}\n              width={GIF_W / GIF_K}\n              height={GIF_H / GIF_K}\n              fit=\"cover\"\n              style={{\n                transform: `scale(${GIF_K})`,\n                imageRendering: \"pixelated\",\n              }}\n            />\n          </div>\n        </PixelBox>\n      </div>\n    </AbsoluteFill>\n  );\n};\n\n// ===========================================================================\n// Scene 2 — Hook. The sponsor line lands word by word, each word snapping\n// through sprite poses — no blur, no glide.\n// ===========================================================================\nconst WordsSnap: React.FC<{\n  text: string;\n  fontSize: number;\n  color?: string;\n  delay?: number;\n  perWord?: number;\n}> = ({ text, fontSize, color = INK, delay = 6, perWord = 7 }) => {\n  const frame = useCurrentFrame();\n  return (\n    <div\n      style={{\n        fontFamily: PIXEL,\n        fontSize,\n        color,\n        lineHeight: 1.5,\n        textAlign: \"center\",\n      }}\n    >\n      {text.split(\" \").map((word, i) => {\n        const q = stepIn(frame, delay + i * perWord, 8, 3);\n        return (\n          <span\n            key={i}\n            style={{\n              display: \"inline-block\",\n              whiteSpace: \"pre\",\n              opacity: q > 0 ? 1 : 0,\n              transform: `translateY(${(1 - q) * 12}px)`,\n            }}\n          >\n            {word}\n            {i < text.split(\" \").length - 1 ? \" \" : \"\"}\n          </span>\n        );\n      })}\n    </div>\n  );\n};\n\nconst HookScene: React.FC = () => (\n  <AbsoluteFill\n    style={{\n      alignItems: \"center\",\n      justifyContent: \"center\",\n      padding: \"0 140px\",\n    }}\n  >\n    <WordsSnap text=\"Say hello to my new sponsor\" fontSize={52} />\n  </AbsoluteFill>\n);\n\n// ===========================================================================\n// Scene 3 — Reveal. The orcdev avatar snaps in inside the pixel frame, the\n// name types itself on with a solid block caret, the tagline settles under.\n// ===========================================================================\nconst NAME = \"OrcDev\";\nconst TYPE_FROM = 26;\nconst TYPE_STEP = 4;\nconst TYPE_DONE = TYPE_FROM + NAME.length * TYPE_STEP;\n\nconst RevealScene: React.FC = () => {\n  const frame = useCurrentFrame();\n  const q = stepIn(frame, 2, 16, 4);\n  const chars = Math.min(\n    NAME.length,\n    Math.max(0, Math.floor((frame - TYPE_FROM) / TYPE_STEP)),\n  );\n  // Solid while typing, then a deterministic blink for the rest of the scene.\n  const caretOn =\n    frame >= TYPE_FROM - TYPE_STEP &&\n    (frame < TYPE_DONE + 6 || Math.floor(frame / 15) % 2 === 0);\n  return (\n    <AbsoluteFill\n      style={{\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        gap: 34,\n      }}\n    >\n      <div\n        style={{\n          opacity: q > 0 ? 1 : 0,\n          transform: `scale(${0.7 + 0.3 * q})`,\n        }}\n      >\n        <PixelBox border={6} color={ORC_GREEN} background={BG}>\n          <Img\n            src={demoAsset(\"orcdev-avatar.jpg\")}\n            style={{\n              display: \"block\",\n              width: 190,\n              height: 190,\n              margin: 14,\n              imageRendering: \"pixelated\",\n            }}\n          />\n        </PixelBox>\n      </div>\n      <div\n        style={{\n          display: \"flex\",\n          alignItems: \"center\",\n          height: 72,\n          fontFamily: PIXEL,\n          fontSize: 64,\n          color: INK,\n        }}\n      >\n        <span>{NAME.slice(0, chars)}</span>\n        {caretOn ? (\n          <span\n            style={{\n              display: \"inline-block\",\n              width: 30,\n              height: 56,\n              marginLeft: 10,\n              background: ORC_GREEN,\n            }}\n          />\n        ) : null}\n      </div>\n    </AbsoluteFill>\n  );\n};\n\n// ===========================================================================\n// Scene 4 — Beats. His own creed, cut into hard-cut word slots:\n// Build / Break / Conquer. The last one lands in orc green.\n// ===========================================================================\n// The last beat carries the outgoing dither cover, so it holds much longer.\nconst BEAT_WORDS = [\"Build\", \"Break\", \"Conquer\"];\nconst BEAT_DURS = [14, 14, 44];\nconst BEAT_STARTS = BEAT_DURS.map((_, i) =>\n  BEAT_DURS.slice(0, i).reduce((a, b) => a + b, 0),\n);\n\nconst BeatsScene: React.FC = () => {\n  const frame = useCurrentFrame();\n  let active = 0;\n  for (let i = 0; i < BEAT_STARTS.length; i++) {\n    if (frame >= BEAT_STARTS[i]) active = i;\n  }\n  const q = stepIn(frame - BEAT_STARTS[active], 0, 6, 3);\n  const last = active === BEAT_WORDS.length - 1;\n  return (\n    <AbsoluteFill style={{ alignItems: \"center\", justifyContent: \"center\" }}>\n      <span\n        style={{\n          fontFamily: PIXEL,\n          fontSize: 96,\n          lineHeight: 1.1,\n          color: last ? ORC_GREEN : INK,\n          opacity: q > 0 ? 1 : 0,\n          transform: `scale(${1.12 - 0.12 * q})`,\n          whiteSpace: \"nowrap\",\n        }}\n      >\n        {BEAT_WORDS[active]}\n      </span>\n    </AbsoluteFill>\n  );\n};\n\n// ===========================================================================\n// Scene 5 — 8bitcn/ui. The flagship: wordmark, the real tagline, and an HP\n// bar that takes the critical hit the tagline promises — three chunky hits\n// with a one-step shake, then the label lands in green.\n// ===========================================================================\nconst HP_CELLS = 10;\nconst HITS = [\n  { at: 58, cells: 7 },\n  { at: 70, cells: 4 },\n  { at: 82, cells: 1 },\n];\n\nconst HpBar: React.FC = () => {\n  const frame = useCurrentFrame();\n  let cells = HP_CELLS;\n  let lastHit = -Infinity;\n  for (const hit of HITS) {\n    if (frame >= hit.at) {\n      cells = hit.cells;\n      lastHit = hit.at;\n    }\n  }\n  // One-step shake for a few frames after each hit.\n  const since = frame - lastHit;\n  const shake = since >= 0 && since < 6 ? (since % 2 === 0 ? -5 : 5) : 0;\n  const barQ = stepIn(frame, 34, 10, 3);\n  const critQ = stepIn(frame, HITS[2].at + 4, 6, 2);\n  // Health goes green → yellow at half → red at the end.\n  const hpColor =\n    cells > HP_CELLS / 2 ? ORC_GREEN : cells > 2 ? HP_YELLOW : HP_RED;\n  return (\n    <div\n      style={{\n        display: \"flex\",\n        flexDirection: \"column\",\n        alignItems: \"center\",\n        gap: 14,\n        opacity: barQ > 0 ? 1 : 0,\n        transform: `translateY(${(1 - barQ) * 12}px)`,\n      }}\n    >\n      <div style={{ transform: `translateX(${shake}px)` }}>\n        <PixelBox border={5} background={BG}>\n          <div style={{ display: \"flex\", gap: 6, margin: \"11px 12px\" }}>\n            {Array.from({ length: HP_CELLS }, (_, i) => (\n              <div\n                key={i}\n                style={{\n                  width: 34,\n                  height: 22,\n                  background: i < cells ? hpColor : \"rgba(250,250,250,0.12)\",\n                }}\n              />\n            ))}\n          </div>\n        </PixelBox>\n      </div>\n      <span\n        style={{\n          fontFamily: PIXEL,\n          fontSize: 30,\n          color: HP_RED,\n          opacity: critQ > 0 ? 1 : 0,\n          transform: `scale(${1.2 - 0.2 * critQ})`,\n        }}\n      >\n        Critical hit\n      </span>\n    </div>\n  );\n};\n\nconst EightbitcnScene: React.FC = () => {\n  const frame = useCurrentFrame();\n  const q = stepIn(frame, 4, 12, 4);\n  const tagQ = stepIn(frame, 18, 10, 3);\n  return (\n    <AbsoluteFill\n      style={{\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        gap: 18,\n        padding: \"0 120px\",\n      }}\n    >\n      <span\n        style={{\n          fontFamily: PIXEL,\n          fontSize: 76,\n          color: INK,\n          opacity: q > 0 ? 1 : 0,\n          transform: `scale(${1.15 - 0.15 * q})`,\n        }}\n      >\n        8bitcn/ui\n      </span>\n      <span\n        style={{\n          fontFamily: SANS,\n          fontWeight: 400,\n          fontSize: 25,\n          color: MUTED,\n          textAlign: \"center\",\n          opacity: tagQ,\n        }}\n      >\n        8-bit components and blocks that feel like a critical hit.\n      </span>\n      <HpBar />\n    </AbsoluteFill>\n  );\n};\n\n// ===========================================================================\n// Scene 6 — Lockup. Remocn ✕ OrcDev snap in from opposite sides in stepped\n// slides, the cross lands between them, orcdev.com settles below.\n// ===========================================================================\nconst LockupScene: React.FC = () => {\n  const frame = useCurrentFrame();\n  const sideQ = stepIn(frame, 6, 18, 5);\n  const leftX = (1 - sideQ) * -64;\n  const rightX = (1 - sideQ) * 64;\n  const crossQ = stepIn(frame, 26, 8, 3);\n  return (\n    <AbsoluteFill\n      style={{\n        alignItems: \"center\",\n        justifyContent: \"center\",\n      }}\n    >\n      <div style={{ display: \"flex\", alignItems: \"center\", gap: 40 }}>\n        <span\n          style={{\n            fontFamily: PIXEL,\n            fontSize: 58,\n            color: INK,\n            opacity: sideQ > 0 ? 1 : 0,\n            transform: `translateX(${leftX}px)`,\n            whiteSpace: \"nowrap\",\n          }}\n        >\n          Remocn\n        </span>\n        <span\n          style={{\n            fontFamily: PIXEL,\n            fontSize: 40,\n            color: FAINT,\n            opacity: crossQ > 0 ? 1 : 0,\n            transform: `scale(${0.5 + 0.5 * crossQ})`,\n          }}\n        >\n          ✕\n        </span>\n        <div\n          style={{\n            display: \"flex\",\n            alignItems: \"center\",\n            gap: 24,\n            opacity: sideQ > 0 ? 1 : 0,\n            transform: `translateX(${rightX}px)`,\n          }}\n        >\n          <PixelBox border={5} color={ORC_GREEN} background={BG}>\n            <Img\n              src={demoAsset(\"orcdev-avatar.jpg\")}\n              style={{\n                display: \"block\",\n                width: 84,\n                height: 84,\n                margin: 10,\n                imageRendering: \"pixelated\",\n              }}\n            />\n          </PixelBox>\n          <span\n            style={{\n              fontFamily: PIXEL,\n              fontSize: 50,\n              color: INK,\n              whiteSpace: \"nowrap\",\n            }}\n          >\n            OrcDev\n          </span>\n        </div>\n      </div>\n    </AbsoluteFill>\n  );\n};\n\n// ===========================================================================\n// Composition root. One persistent dithering shader carries the whole video —\n// the paper.design dots/random preset exactly as configured: black back,\n// #008000 dots, size 5.2 — pushed back by a vignette so it stays a texture.\n// ===========================================================================\nexport const SponsorOrcdevDemo: React.FC = () => {\n  const pixelReady = usePixelFont();\n  if (!pixelReady) {\n    return <AbsoluteFill style={{ background: BG }} />;\n  }\n  return (\n    <AbsoluteFill style={{ background: BG }}>\n      <ShaderDithering\n        speed={1}\n        colorBack={BG}\n        colorFront={DOT_GREEN}\n        shape=\"dots\"\n        type=\"random\"\n        size={5.2}\n      />\n      {/* Vignette scrim — keeps the dither a texture, not a subject. */}\n      <AbsoluteFill\n        style={{\n          background:\n            \"radial-gradient(120% 120% at 50% 42%, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.92) 100%)\",\n        }}\n      />\n\n      <TransitionSeries>\n        {/* 1 — Pixelated orc gif */}\n        <TransitionSeries.Sequence durationInFrames={S_INTRO}>\n          <IntroScene />\n        </TransitionSeries.Sequence>\n        <TransitionSeries.Transition\n          timing={linearTiming({ durationInFrames: T_DD })}\n          presentation={greenDither()}\n        />\n\n        {/* 2 — Hook */}\n        <TransitionSeries.Sequence durationInFrames={S_HOOK}>\n          <HookScene />\n        </TransitionSeries.Sequence>\n        <TransitionSeries.Transition\n          timing={linearTiming({ durationInFrames: T_DD })}\n          presentation={greenDither()}\n        />\n\n        {/* 3 — OrcDev reveal */}\n        <TransitionSeries.Sequence durationInFrames={S_REVEAL}>\n          <RevealScene />\n        </TransitionSeries.Sequence>\n\n        {/* 4 — Build / Break / Conquer (hard cut in) */}\n        <TransitionSeries.Sequence durationInFrames={S_BEATS}>\n          <BeatsScene />\n        </TransitionSeries.Sequence>\n        <TransitionSeries.Transition\n          timing={linearTiming({ durationInFrames: T_DD })}\n          presentation={greenDither()}\n        />\n\n        {/* 5 — 8bitcn/ui */}\n        <TransitionSeries.Sequence durationInFrames={S_8BIT}>\n          <EightbitcnScene />\n        </TransitionSeries.Sequence>\n        <TransitionSeries.Transition\n          timing={linearTiming({ durationInFrames: T_DD })}\n          presentation={greenDither()}\n        />\n\n        {/* 6 — Lockup + URL */}\n        <TransitionSeries.Sequence durationInFrames={S_LOCKUP}>\n          <LockupScene />\n        </TransitionSeries.Sequence>\n      </TransitionSeries>\n    </AbsoluteFill>\n  );\n};\n",
      "type": "registry:component",
      "target": "demos/sponsor-orcdev/index.tsx"
    },
    {
      "path": "src/lib/demo-assets.ts",
      "content": "import { staticFile } from \"remotion\";\n\n// Demo assets are loaded from absolute URLs so a demo installed into another\n// project via the registry renders identically without copying this repo's\n// public/ directory. The same URLs are used on the site and in local renders,\n// which keeps a single code path (network access is required for rendering).\n//\n// Override with REMOTION_DEMO_ASSETS_BASE — only REMOTION_-prefixed env vars\n// reach Remotion compositions (next.config.js additionally inlines it for the\n// site's <Player>). Two override forms:\n//   - \"local\" — serve straight from this repo's public/ via staticFile();\n//     works in Remotion Studio, CLI renders and the Next dev site. Set it in\n//     the gitignored .env so previews never depend on pushed assets.\n//   - any URL — e.g. a local static server (http://127.0.0.1:8123).\nexport const DEMO_ASSETS_BASE =\n  process.env.REMOTION_DEMO_ASSETS_BASE ||\n  \"https://raw.githubusercontent.com/Remocn/remocn-collections/main/public\";\n\nexport const demoAsset = (path: string): string => {\n  const clean = path.replace(/^\\/+/, \"\");\n  if (DEMO_ASSETS_BASE === \"local\") return staticFile(clean);\n  return `${DEMO_ASSETS_BASE}/${clean}`;\n};\n",
      "type": "registry:component",
      "target": "lib/demo-assets.ts"
    },
    {
      "path": "src/demos/sponsor-orcdev/prompt.md",
      "content": "<!-- TODO(draft): placeholder written by AI — replace with the real prompt used to generate this video -->\n\nI need a sponsor shoutout video for OrcDev, done fully in the 8bitcn pixel-art register — black background, that green dithering shader as the backdrop, Geist Pixel Square for headlines. Pull the orc green from their avatar as the only accent color and keep every motion snapped/stepped like sprite frames, no smooth easing or blur. Open on their nod gif crunched into pixels inside an 8bitcn frame, say \"Say hello to my new sponsor\" word by word, then reveal the avatar and type out \"OrcDev\" with a blocky caret and the \"Web dev warrior\" tagline. Add a quick Build / Break / Conquer beat and show off their 8bitcn/ui project with an HP bar taking a few hits ending on \"Critical hit\". End on a Remocn x OrcDev lockup with orcdev.com. Use remocn's pixel/8bit components where it fits.\n",
      "type": "registry:file",
      "target": "demos/sponsor-orcdev/prompt.md"
    }
  ],
  "docs": "Register the composition in your Remotion Root:\n\n  import { SponsorOrcdevDemo } from \"@/demos/sponsor-orcdev\";\n  <Composition id=\"sponsor-orcdev\" component={SponsorOrcdevDemo} durationInFrames={482} fps={30} width={1280} height={720} />\n\nRequires Tailwind v4 wired into Remotion (@remotion/tailwind-v4).\nRender locally: npx remotion render sponsor-orcdev out/sponsor-orcdev.mp4 --gl=angle",
  "type": "registry:block"
}