{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "pixelate-region",
  "title": "Pixelate Region",
  "description": "Cover rectangles of a scene with an opaque mosaic while the rest passes through untouched — redact keys, addresses and personal data before a demo goes out.",
  "dependencies": ["remotion"],
  "registryDependencies": ["@remocn/canvas-presentation"],
  "files": [
    {
      "path": "registry/remocn/pixelate-region/index.tsx",
      "content": "\"use client\";\n\nimport type React from \"react\";\nimport { AbsoluteFill, useVideoConfig } from \"remotion\";\nimport {\n  type CanvasFilterProps,\n  makeCanvasFilter,\n  makeFilterShader,\n} from \"@/lib/remocn/canvas-presentation\";\n\nexport type PixelateRect = {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n};\n\nexport type PixelateRegionProps = {\n  regions: PixelateRect[];\n  cellSize?: number;\n};\n\nconst MAX_REGIONS = 8;\n\nconst DEFAULTS = {\n  cellSize: 24,\n};\n\ntype NormalizedProps = {\n  rects: PixelateRect[];\n  cellX: number;\n  cellY: number;\n};\n\nconst FRAGMENT_SHADER = `#version 300 es\nprecision highp float;\n\nuniform sampler2D u_scene;\nuniform vec4 u_regions[${MAX_REGIONS}];\nuniform int u_region_count;\nuniform vec2 u_cell;\n\nin vec2 v_uv;\nout vec4 outColor;\n\nconst int TAPS = 3;\n\nvec4 cellAverage(vec2 center, vec2 cell) {\n  vec4 sum = vec4(0.0);\n  for (int y = 0; y < TAPS; y++) {\n    for (int x = 0; x < TAPS; x++) {\n      vec2 offset =\n        (vec2(float(x), float(y)) + 0.5) / float(TAPS) - 0.5;\n      sum += texture(u_scene, center + offset * cell);\n    }\n  }\n  return sum / float(TAPS * TAPS);\n}\n\nvoid main() {\n  vec4 result = texture(u_scene, v_uv);\n  vec2 cell = max(u_cell, vec2(0.0005));\n\n  for (int i = 0; i < ${MAX_REGIONS}; i++) {\n    if (i >= u_region_count) {\n      continue;\n    }\n    vec4 region = u_regions[i];\n    vec2 lo = region.xy;\n    vec2 hi = region.xy + region.zw;\n    vec2 hit = step(lo, v_uv) * step(v_uv, hi);\n    if (hit.x * hit.y < 0.5) {\n      continue;\n    }\n    vec2 center = lo + (floor((v_uv - lo) / cell) + 0.5) * cell;\n    result = vec4(cellAverage(center, cell).rgb, 1.0);\n  }\n\n  outColor = result;\n}`;\n\nconst shader = makeFilterShader<NormalizedProps>(\n  FRAGMENT_SHADER,\n  ({ gl, uniform, passedProps }) => {\n    const { rects, cellX, cellY } = passedProps;\n    const packed = new Float32Array(MAX_REGIONS * 4);\n    const count = Math.min(rects.length, MAX_REGIONS);\n    for (let i = 0; i < count; i++) {\n      const rect = rects[i];\n      packed[i * 4] = rect.x;\n      packed[i * 4 + 1] = rect.y;\n      packed[i * 4 + 2] = rect.width;\n      packed[i * 4 + 3] = rect.height;\n    }\n    gl.uniform4fv(uniform(\"u_regions[0]\"), packed);\n    gl.uniform1i(uniform(\"u_region_count\"), count);\n    gl.uniform2f(uniform(\"u_cell\"), cellX, cellY);\n  },\n);\n\nconst PixelateRegionFallback: React.FC<NormalizedProps & CanvasFilterProps> = ({\n  children,\n  rects,\n}) => (\n  <AbsoluteFill>\n    {children}\n    {rects.map((rect) => (\n      <div\n        key={`${rect.x}-${rect.y}-${rect.width}-${rect.height}`}\n        style={{\n          position: \"absolute\",\n          left: `${rect.x * 100}%`,\n          top: `${rect.y * 100}%`,\n          width: `${rect.width * 100}%`,\n          height: `${rect.height * 100}%`,\n          background: \"#14161c\",\n        }}\n      />\n    ))}\n  </AbsoluteFill>\n);\n\nconst PixelateRegionCanvas = makeCanvasFilter<NormalizedProps>({\n  shader,\n  fallback: PixelateRegionFallback,\n});\n\nexport const PixelateRegion: React.FC<\n  PixelateRegionProps & CanvasFilterProps\n> = ({ regions, cellSize = DEFAULTS.cellSize, children }) => {\n  const { width, height } = useVideoConfig();\n\n  if (regions.length > MAX_REGIONS) {\n    throw new Error(\n      `pixelate-region: at most ${MAX_REGIONS} regions can be covered at once, received ${regions.length}. Dropping any of them would leave what it covered visible, so nest a second PixelateRegion instead.`,\n    );\n  }\n\n  const rects = regions.map((region) => ({\n    x: region.x / width,\n    y: region.y / height,\n    width: region.width / width,\n    height: region.height / height,\n  }));\n\n  return (\n    <PixelateRegionCanvas\n      rects={rects}\n      cellX={cellSize / width}\n      cellY={cellSize / height}\n    >\n      {children}\n    </PixelateRegionCanvas>\n  );\n};\n",
      "type": "registry:component",
      "target": "components/remocn/pixelate-region.tsx"
    }
  ],
  "type": "registry:component"
}
