@twick/studio 0.15.25 → 0.15.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/properties/generate-captions.d.ts +3 -2
- package/dist/helpers/generate-captions.service.d.ts +4 -4
- package/dist/hooks/use-generate-captions.d.ts +2 -2
- package/dist/hooks/use-studio-operation.d.ts +0 -2
- package/dist/index.js +57 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +57 -17
- package/dist/index.mjs.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/package.json +15 -15
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/shared/src/utils.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/defaultAttributes.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/Icon.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/createLucideIcon.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/align-center.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/align-left.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/align-right.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/bold.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-down.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-right.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/circle-check.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/circle-x.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/circle.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/clapperboard.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/download.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/file.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/image.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/italic.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/loader-circle.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/message-square.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/music-2.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/music.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/palette.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/pause.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/play.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/plus.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/rectangle-horizontal.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/rectangle-vertical.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/ruler.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/save.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/scissors.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/search.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/sparkles.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/square.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/trash-2.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/type.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/upload.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/video.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/volume-2.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/volume-x.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/wand-sparkles.js","../src/components/toolbar.tsx","../src/components/header.tsx","../src/hooks/use-studio-manager.tsx","../src/hooks/use-cloud-media-upload.ts","../src/components/shared/cloud-media-upload.tsx","../src/components/shared/media-manager.ts","../src/components/shared/url-input.tsx","../src/context/media-context.tsx","../src/hooks/use-media-panel.ts","../src/hooks/use-audio-preview.ts","../src/components/panel/audio-panel.tsx","../src/components/shared/search-input.tsx","../src/helpers/asset-library.ts","../src/components/container/audio-panel-container.tsx","../src/components/panel/image-panel.tsx","../src/components/container/image-panel-container.tsx","../src/hooks/use-video-preview.ts","../src/components/panel/video-panel.tsx","../src/components/container/video-panel-container.tsx","../src/components/panel/text-panel.tsx","../src/hooks/use-text-panel.ts","../src/components/container/text-panel-container.tsx","../src/components/panel/text-style-panel.tsx","../src/components/container/text-style-panel-container.tsx","../../effects/dist/catalog.js","../src/hooks/use-effect-panel.ts","../src/helpers/effect-preview-manager.ts","../src/components/panel/effect-style-panel.tsx","../src/components/container/effect-style-panel-container.tsx","../src/components/panel/captions-panel.tsx","../src/helpers/constant.ts","../src/hooks/use-captions-panel.ts","../src/components/container/captions-panel-container.tsx","../src/components/container/generate-media-panel-container.tsx","../src/templates/default-templates.ts","../src/components/panel/template-gallery-panel.tsx","../src/hooks/use-screen-recorder.ts","../src/components/panel/record-panel.tsx","../src/components/panel/annotations-panel.tsx","../src/components/panel/chapters-panel.tsx","../src/components/panel/script-panel.tsx","../src/components/container/element-panel-container.tsx","../src/components/properties/property-row.tsx","../src/components/shared/accordion-item.tsx","../src/components/properties/element-props.tsx","../src/components/properties/text-effects.tsx","../src/components/properties/animation.tsx","../src/components/properties/caption-prop.tsx","../src/helpers/volume-db.ts","../src/components/properties/playback-props.tsx","../../media-utils/dist/index.mjs","../src/components/properties/generate-captions.tsx","../src/components/properties/text-props.tsx","../src/components/properties/annotation-style-panel.tsx","../src/components/container/properties-panel-container.tsx","../src/hooks/use-studio-operation.ts","../src/components/twick-studio.tsx","../src/hooks/use-generate-captions.ts","../src/components/panel/circle-panel.tsx","../src/components/panel/rect-panel.tsx","../src/profiles/index.ts","../src/helpers/export-project-bundle.ts"],"sourcesContent":["/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n};\n\nexport { hasA11yProp, mergeClasses, toCamelCase, toKebabCase, toPascalCase };\n//# sourceMappingURL=utils.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { mergeClasses, hasA11yProp } from './shared/src/utils.js';\n\nconst Icon = forwardRef(\n ({\n color = \"currentColor\",\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = \"\",\n children,\n iconNode,\n ...rest\n }, ref) => createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,\n className: mergeClasses(\"lucide\", className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n )\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from './shared/src/utils.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M17 12H7\", key: \"16if0g\" }],\n [\"path\", { d: \"M19 18H5\", key: \"18s9l3\" }],\n [\"path\", { d: \"M21 6H3\", key: \"1jwq7v\" }]\n];\nconst AlignCenter = createLucideIcon(\"align-center\", __iconNode);\n\nexport { __iconNode, AlignCenter as default };\n//# sourceMappingURL=align-center.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 12H3\", key: \"6jk70r\" }],\n [\"path\", { d: \"M17 18H3\", key: \"1amg6g\" }],\n [\"path\", { d: \"M21 6H3\", key: \"1jwq7v\" }]\n];\nconst AlignLeft = createLucideIcon(\"align-left\", __iconNode);\n\nexport { __iconNode, AlignLeft as default };\n//# sourceMappingURL=align-left.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 12H9\", key: \"dn1m92\" }],\n [\"path\", { d: \"M21 18H7\", key: \"1ygte8\" }],\n [\"path\", { d: \"M21 6H3\", key: \"1jwq7v\" }]\n];\nconst AlignRight = createLucideIcon(\"align-right\", __iconNode);\n\nexport { __iconNode, AlignRight as default };\n//# sourceMappingURL=align-right.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n { d: \"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\", key: \"mg9rjx\" }\n ]\n];\nconst Bold = createLucideIcon(\"bold\", __iconNode);\n\nexport { __iconNode, Bold as default };\n//# sourceMappingURL=bold.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"m6 9 6 6 6-6\", key: \"qrunsl\" }]];\nconst ChevronDown = createLucideIcon(\"chevron-down\", __iconNode);\n\nexport { __iconNode, ChevronDown as default };\n//# sourceMappingURL=chevron-down.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"m9 18 6-6-6-6\", key: \"mthhwq\" }]];\nconst ChevronRight = createLucideIcon(\"chevron-right\", __iconNode);\n\nexport { __iconNode, ChevronRight as default };\n//# sourceMappingURL=chevron-right.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"m9 12 2 2 4-4\", key: \"dzmm74\" }]\n];\nconst CircleCheck = createLucideIcon(\"circle-check\", __iconNode);\n\nexport { __iconNode, CircleCheck as default };\n//# sourceMappingURL=circle-check.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"m15 9-6 6\", key: \"1uzhvr\" }],\n [\"path\", { d: \"m9 9 6 6\", key: \"z0biqf\" }]\n];\nconst CircleX = createLucideIcon(\"circle-x\", __iconNode);\n\nexport { __iconNode, CircleX as default };\n//# sourceMappingURL=circle-x.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }]];\nconst Circle = createLucideIcon(\"circle\", __iconNode);\n\nexport { __iconNode, Circle as default };\n//# sourceMappingURL=circle.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n { d: \"M20.2 6 3 11l-.9-2.4c-.3-1.1.3-2.2 1.3-2.5l13.5-4c1.1-.3 2.2.3 2.5 1.3Z\", key: \"1tn4o7\" }\n ],\n [\"path\", { d: \"m6.2 5.3 3.1 3.9\", key: \"iuk76l\" }],\n [\"path\", { d: \"m12.4 3.4 3.1 4\", key: \"6hsd6n\" }],\n [\"path\", { d: \"M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z\", key: \"ltgou9\" }]\n];\nconst Clapperboard = createLucideIcon(\"clapperboard\", __iconNode);\n\nexport { __iconNode, Clapperboard as default };\n//# sourceMappingURL=clapperboard.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 15V3\", key: \"m9g1x1\" }],\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }],\n [\"path\", { d: \"m7 10 5 5 5-5\", key: \"brsn70\" }]\n];\nconst Download = createLucideIcon(\"download\", __iconNode);\n\nexport { __iconNode, Download as default };\n//# sourceMappingURL=download.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }]\n];\nconst File = createLucideIcon(\"file\", __iconNode);\n\nexport { __iconNode, File as default };\n//# sourceMappingURL=file.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", ry: \"2\", key: \"1m3agn\" }],\n [\"circle\", { cx: \"9\", cy: \"9\", r: \"2\", key: \"af1f0g\" }],\n [\"path\", { d: \"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\", key: \"1xmnt7\" }]\n];\nconst Image = createLucideIcon(\"image\", __iconNode);\n\nexport { __iconNode, Image as default };\n//# sourceMappingURL=image.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"line\", { x1: \"19\", x2: \"10\", y1: \"4\", y2: \"4\", key: \"15jd3p\" }],\n [\"line\", { x1: \"14\", x2: \"5\", y1: \"20\", y2: \"20\", key: \"bu0au3\" }],\n [\"line\", { x1: \"15\", x2: \"9\", y1: \"4\", y2: \"20\", key: \"uljnxc\" }]\n];\nconst Italic = createLucideIcon(\"italic\", __iconNode);\n\nexport { __iconNode, Italic as default };\n//# sourceMappingURL=italic.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"M21 12a9 9 0 1 1-6.219-8.56\", key: \"13zald\" }]];\nconst LoaderCircle = createLucideIcon(\"loader-circle\", __iconNode);\n\nexport { __iconNode, LoaderCircle as default };\n//# sourceMappingURL=loader-circle.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\", key: \"1lielz\" }]\n];\nconst MessageSquare = createLucideIcon(\"message-square\", __iconNode);\n\nexport { __iconNode, MessageSquare as default };\n//# sourceMappingURL=message-square.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"8\", cy: \"18\", r: \"4\", key: \"1fc0mg\" }],\n [\"path\", { d: \"M12 18V2l7 4\", key: \"g04rme\" }]\n];\nconst Music2 = createLucideIcon(\"music-2\", __iconNode);\n\nexport { __iconNode, Music2 as default };\n//# sourceMappingURL=music-2.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M9 18V5l12-2v13\", key: \"1jmyc2\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"circle\", { cx: \"18\", cy: \"16\", r: \"3\", key: \"1hluhg\" }]\n];\nconst Music = createLucideIcon(\"music\", __iconNode);\n\nexport { __iconNode, Music as default };\n//# sourceMappingURL=music.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z\",\n key: \"e79jfc\"\n }\n ],\n [\"circle\", { cx: \"13.5\", cy: \"6.5\", r: \".5\", fill: \"currentColor\", key: \"1okk4w\" }],\n [\"circle\", { cx: \"17.5\", cy: \"10.5\", r: \".5\", fill: \"currentColor\", key: \"f64h9f\" }],\n [\"circle\", { cx: \"6.5\", cy: \"12.5\", r: \".5\", fill: \"currentColor\", key: \"qy21gx\" }],\n [\"circle\", { cx: \"8.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"fotxhn\" }]\n];\nconst Palette = createLucideIcon(\"palette\", __iconNode);\n\nexport { __iconNode, Palette as default };\n//# sourceMappingURL=palette.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"zuxfzm\" }],\n [\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"1okwgv\" }]\n];\nconst Pause = createLucideIcon(\"pause\", __iconNode);\n\nexport { __iconNode, Pause as default };\n//# sourceMappingURL=pause.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"polygon\", { points: \"6 3 20 12 6 21 6 3\", key: \"1oa8hb\" }]];\nconst Play = createLucideIcon(\"play\", __iconNode);\n\nexport { __iconNode, Play as default };\n//# sourceMappingURL=play.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }]\n];\nconst Plus = createLucideIcon(\"plus\", __iconNode);\n\nexport { __iconNode, Plus as default };\n//# sourceMappingURL=plus.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"20\", height: \"12\", x: \"2\", y: \"6\", rx: \"2\", key: \"9lu3g6\" }]\n];\nconst RectangleHorizontal = createLucideIcon(\"rectangle-horizontal\", __iconNode);\n\nexport { __iconNode, RectangleHorizontal as default };\n//# sourceMappingURL=rectangle-horizontal.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"12\", height: \"20\", x: \"6\", y: \"2\", rx: \"2\", key: \"1oxtiu\" }]\n];\nconst RectangleVertical = createLucideIcon(\"rectangle-vertical\", __iconNode);\n\nexport { __iconNode, RectangleVertical as default };\n//# sourceMappingURL=rectangle-vertical.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z\",\n key: \"icamh8\"\n }\n ],\n [\"path\", { d: \"m14.5 12.5 2-2\", key: \"inckbg\" }],\n [\"path\", { d: \"m11.5 9.5 2-2\", key: \"fmmyf7\" }],\n [\"path\", { d: \"m8.5 6.5 2-2\", key: \"vc6u1g\" }],\n [\"path\", { d: \"m17.5 15.5 2-2\", key: \"wo5hmg\" }]\n];\nconst Ruler = createLucideIcon(\"ruler\", __iconNode);\n\nexport { __iconNode, Ruler as default };\n//# sourceMappingURL=ruler.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z\",\n key: \"1c8476\"\n }\n ],\n [\"path\", { d: \"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\", key: \"1ydtos\" }],\n [\"path\", { d: \"M7 3v4a1 1 0 0 0 1 1h7\", key: \"t51u73\" }]\n];\nconst Save = createLucideIcon(\"save\", __iconNode);\n\nexport { __iconNode, Save as default };\n//# sourceMappingURL=save.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M8.12 8.12 12 12\", key: \"1alkpv\" }],\n [\"path\", { d: \"M20 4 8.12 15.88\", key: \"xgtan2\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"path\", { d: \"M14.8 14.8 20 20\", key: \"ptml3r\" }]\n];\nconst Scissors = createLucideIcon(\"scissors\", __iconNode);\n\nexport { __iconNode, Scissors as default };\n//# sourceMappingURL=scissors.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m21 21-4.34-4.34\", key: \"14j7rj\" }],\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }]\n];\nconst Search = createLucideIcon(\"search\", __iconNode);\n\nexport { __iconNode, Search as default };\n//# sourceMappingURL=search.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z\",\n key: \"4pj2yx\"\n }\n ],\n [\"path\", { d: \"M20 3v4\", key: \"1olli1\" }],\n [\"path\", { d: \"M22 5h-4\", key: \"1gvqau\" }],\n [\"path\", { d: \"M4 17v2\", key: \"vumght\" }],\n [\"path\", { d: \"M5 18H3\", key: \"zchphs\" }]\n];\nconst Sparkles = createLucideIcon(\"sparkles\", __iconNode);\n\nexport { __iconNode, Sparkles as default };\n//# sourceMappingURL=sparkles.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }]\n];\nconst Square = createLucideIcon(\"square\", __iconNode);\n\nexport { __iconNode, Square as default };\n//# sourceMappingURL=square.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\", key: \"4alrt4\" }],\n [\"path\", { d: \"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\", key: \"v07s0e\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"11\", y2: \"17\", key: \"1uufr5\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"11\", y2: \"17\", key: \"xtxkd\" }]\n];\nconst Trash2 = createLucideIcon(\"trash-2\", __iconNode);\n\nexport { __iconNode, Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 4v16\", key: \"1654pz\" }],\n [\"path\", { d: \"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2\", key: \"e0r10z\" }],\n [\"path\", { d: \"M9 20h6\", key: \"s66wpe\" }]\n];\nconst Type = createLucideIcon(\"type\", __iconNode);\n\nexport { __iconNode, Type as default };\n//# sourceMappingURL=type.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 3v12\", key: \"1x0j5s\" }],\n [\"path\", { d: \"m17 8-5-5-5 5\", key: \"7q97r8\" }],\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }]\n];\nconst Upload = createLucideIcon(\"upload\", __iconNode);\n\nexport { __iconNode, Upload as default };\n//# sourceMappingURL=upload.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\",\n key: \"ftymec\"\n }\n ],\n [\"rect\", { x: \"2\", y: \"6\", width: \"14\", height: \"12\", rx: \"2\", key: \"158x01\" }]\n];\nconst Video = createLucideIcon(\"video\", __iconNode);\n\nexport { __iconNode, Video as default };\n//# sourceMappingURL=video.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z\",\n key: \"uqj9uw\"\n }\n ],\n [\"path\", { d: \"M16 9a5 5 0 0 1 0 6\", key: \"1q6k2b\" }],\n [\"path\", { d: \"M19.364 18.364a9 9 0 0 0 0-12.728\", key: \"ijwkga\" }]\n];\nconst Volume2 = createLucideIcon(\"volume-2\", __iconNode);\n\nexport { __iconNode, Volume2 as default };\n//# sourceMappingURL=volume-2.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z\",\n key: \"uqj9uw\"\n }\n ],\n [\"line\", { x1: \"22\", x2: \"16\", y1: \"9\", y2: \"15\", key: \"1ewh16\" }],\n [\"line\", { x1: \"16\", x2: \"22\", y1: \"9\", y2: \"15\", key: \"5ykzw1\" }]\n];\nconst VolumeX = createLucideIcon(\"volume-x\", __iconNode);\n\nexport { __iconNode, VolumeX as default };\n//# sourceMappingURL=volume-x.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72\",\n key: \"ul74o6\"\n }\n ],\n [\"path\", { d: \"m14 7 3 3\", key: \"1r5n42\" }],\n [\"path\", { d: \"M5 6v4\", key: \"ilb8ba\" }],\n [\"path\", { d: \"M19 14v4\", key: \"blhpug\" }],\n [\"path\", { d: \"M10 2v2\", key: \"7u0qdc\" }],\n [\"path\", { d: \"M7 8H3\", key: \"zfb6yr\" }],\n [\"path\", { d: \"M21 16h-4\", key: \"1cnmox\" }],\n [\"path\", { d: \"M11 3H9\", key: \"1obp7u\" }]\n];\nconst WandSparkles = createLucideIcon(\"wand-sparkles\", __iconNode);\n\nexport { __iconNode, WandSparkles as default };\n//# sourceMappingURL=wand-sparkles.js.map\n","/**\n * Toolbar Component\n * \n * A vertical toolbar that provides quick access to different editing tools\n * and media types. Displays icons with labels and optional keyboard shortcuts.\n * \n * @component\n * @param {Object} props\n * @param {string} props.selectedTool - Currently selected tool ID\n * @param {(tool: string) => void} props.setSelectedTool - Callback to update selected tool\n * \n * @example\n * ```tsx\n * <Toolbar\n * selectedTool=\"text\"\n * setSelectedTool={(tool) => console.log(`Selected ${tool}`)}\n * />\n * ```\n */\n\nimport { \n Type, \n Upload, \n Video,\n Image, \n Music,\n Circle,\n MessageSquare,\n Plus,\n Square,\n Wand2,\n File,\n} from 'lucide-react'\nimport type { ToolCategory } from '../types'\n\nconst defaultToolCategories: ToolCategory[] = [\n // { id: 'templates', name: 'Templates', icon: 'Plus', description: 'Start from a project template' },\n // { id: 'record', name: 'Record', icon: 'Upload', description: 'Record screen and import clip' },\n { id: 'video', name: 'Video', icon: 'Video', description: 'Add a video element' },\n { id: 'image', name: 'Image', icon: 'Image', description: 'Add an image element' },\n { id: 'audio', name: 'Audio', icon: 'Audio', description: 'Add an audio element' },\n { id: 'text', name: 'Text', icon: 'Type', description: 'Add text elements' },\n { id: 'text-style', name: 'Text Style', icon: 'Type', description: 'Apply text style presets' },\n { id: 'effect', name: 'Effect', icon: 'Wand2', description: 'Apply GL video effects' },\n { id: 'shape', name: 'Shape', icon: 'Square', description: 'Add lines, arrows, boxes, and circles' },\n // { id: 'chapters', name: 'Chapters', icon: 'File', description: 'Manage chapter markers' },\n // { id: 'script', name: 'Script', icon: 'Type', description: 'Build timeline from a script outline' },\n { id: 'caption', name: 'Caption', icon: 'MessageSquare', description: 'Manage captions'},\n { id: 'generate-media', name: 'Generate', icon: 'Wand2', description: 'Generate image or video with AI'},\n]\n\nconst getIcon = (iconName: string) => {\n switch (iconName) {\n case 'Plus': return Plus\n case 'Type': return Type\n case 'Upload': return Upload\n case 'Square': return Square\n case 'Image': return Image\n case 'Video': return Video\n case 'Audio': return Music\n case 'Circle': return Circle\n case 'Rect': return Square\n case 'MessageSquare': return MessageSquare\n case 'Wand2': return Wand2\n case 'File': return File\n default: return Plus\n }\n}\n\nexport function Toolbar({\n selectedTool,\n setSelectedTool,\n customTools = [],\n hiddenTools = [],\n}: {\n selectedTool: string;\n setSelectedTool: (tool: string) => void;\n customTools?: ToolCategory[];\n hiddenTools?: string[];\n}) {\n\n const mergedTools = [...defaultToolCategories, ...customTools].filter(\n (tool) => !hiddenTools.includes(tool.id)\n );\n const handleToolSelect = (toolId: string) => {\n setSelectedTool(toolId)\n }\n\n return (\n <div className=\"sidebar\">\n {/* Main Tools */}\n {mergedTools.map((tool) => {\n const Icon = getIcon(tool.icon)\n const isSelected = selectedTool === tool.id\n \n const tooltipText = `${tool.name}${tool.shortcut ? ` (${tool.shortcut})` : ''}`;\n return (\n <div\n key={tool.id}\n onClick={() => handleToolSelect(tool.id)}\n className={`toolbar-btn ${isSelected ? 'active' : ''}`}\n title={tooltipText}\n data-tooltip={tooltipText}\n >\n <Icon className=\"icon-sm\" />\n <span className=\"toolbar-label\">\n {tool.name}\n </span>\n </div>\n )\n })}\n </div>\n )\n}\n","/**\n * StudioHeader Component\n *\n * The top header bar of the studio interface. Contains the studio logo,\n * orientation controls, and action divs for saving and exporting.\n *\n * @component\n * @param {Object} props\n * @param {(resolution: Size) => void} props.setVideoResolution - Callback to update canvas resolution\n *\n * @example\n * ```tsx\n * <StudioHeader\n * setVideoResolution={(size) => console.log(`New size: ${size.width}x${size.height}`)}\n * />\n * ```\n */\n\nimport type { Size } from \"@twick/timeline\";\nimport { Save, Download, Clapperboard, File, Plus, RectangleVertical, RectangleHorizontal } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\n\ninterface StudioHeaderProps {\n setVideoResolution: (resolution: Size) => void;\n onNewProject: () => void;\n onLoadProject: () => void;\n onSaveProject: () => void;\n onExportVideo: () => void;\n onExportCaptions: (format: \"srt\" | \"vtt\") => void;\n onExportChapters: (format: \"youtube\" | \"json\") => void;\n}\nexport const StudioHeader = ({\n setVideoResolution,\n onNewProject,\n onLoadProject,\n onSaveProject,\n onExportVideo,\n}: StudioHeaderProps) => {\n const [orientation, setOrientation] = useState<\"horizontal\" | \"vertical\">(\n \"vertical\"\n );\n\n useEffect(() => {\n const orientation = localStorage.getItem(\"orientation\");\n if (orientation) {\n setOrientation(orientation as \"horizontal\" | \"vertical\");\n }\n }, []);\n\n const handleOrientationChange = (nextOrientation: \"horizontal\" | \"vertical\") => {\n if (nextOrientation === orientation) return;\n\n const confirmMessage =\n \"Changing orientation will create a new project with the new resolution. Do you want to continue?\";\n\n if (!window.confirm(confirmMessage)) {\n return;\n }\n\n // Create a fresh project for the new resolution\n onNewProject();\n setOrientation(nextOrientation);\n };\n\n useEffect(() => {\n if (orientation === \"horizontal\") {\n localStorage.setItem(\"orientation\", \"horizontal\");\n setVideoResolution({ width: 1280, height: 720 });\n } else {\n localStorage.setItem(\"orientation\", \"vertical\");\n setVideoResolution({ width: 720, height: 1280 });\n }\n }, [orientation]);\n\n return (\n <header className=\"header\">\n <div className=\"flex-container\">\n <Clapperboard className=\"icon-lg accent-purple\" />\n <h1 className=\"text-gradient\">\n Twick Studio\n </h1>\n <div className=\"header-separator\"></div>\n <div className=\"flex-container\" style={{ gap: \"0.5rem\" }}>\n <span className=\"text-sm opacity-80\">Orientation</span>\n <button\n className={`btn-ghost ${orientation === \"vertical\" ? \"btn-primary\" : \"\"}`}\n title=\"Portrait (720×1280)\"\n onClick={() => handleOrientationChange(\"vertical\")}\n >\n <RectangleVertical className=\"icon-sm\" />\n\n </button>\n <button\n className={`btn-ghost ${orientation === \"horizontal\" ? \"btn-primary\" : \"\"}`}\n title=\"Landscape (1280×720)\"\n onClick={() => handleOrientationChange(\"horizontal\")}\n >\n <RectangleHorizontal className=\"icon-sm\" />\n\n </button>\n </div>\n </div>\n <div className=\"flex-container\">\n <button\n className=\"btn-ghost\"\n title=\"New Project\"\n onClick={onNewProject}\n >\n <Plus className=\"icon-sm\" />\n New Project\n </button>\n <button\n className=\"btn-ghost\"\n title=\"Load Project\"\n onClick={onLoadProject}\n >\n <File className=\"icon-sm\" />\n Load Project\n </button>\n <button\n className=\"btn-ghost\"\n title=\"Save Draft\"\n onClick={onSaveProject}\n >\n <Save className=\"icon-sm\" />\n Save Draft\n </button>\n {/* <button\n className=\"btn-ghost\"\n title=\"Export captions as SRT\"\n onClick={() => onExportCaptions(\"srt\")}\n >\n <Download className=\"icon-sm\" />\n SRT\n </button>\n <button\n className=\"btn-ghost\"\n title=\"Export captions as VTT\"\n onClick={() => onExportCaptions(\"vtt\")}\n >\n <Download className=\"icon-sm\" />\n VTT\n </button>\n <button\n className=\"btn-ghost\"\n title=\"Export chapters as YouTube timestamps\"\n onClick={() => onExportChapters(\"youtube\")}\n >\n <Download className=\"icon-sm\" />\n Chapters TXT\n </button>\n <button\n className=\"btn-ghost\"\n title=\"Export chapters as JSON\"\n onClick={() => onExportChapters(\"json\")}\n >\n <Download className=\"icon-sm\" />\n Chapters JSON\n </button> */}\n <button\n className=\"btn-primary\"\n title=\"Export\"\n onClick={onExportVideo}\n >\n <Download className=\"icon-sm\" />\n Export\n </button>\n </div>\n </header>\n );\n};\n\nexport default StudioHeader;\n","/**\n * useStudioManager Hook\n *\n * A custom hook that manages the studio's state and operations.\n * Handles tool selection, element management, and timeline interactions.\n *\n * @returns {Object} Studio manager methods and state\n * @property {string} selectedTool - Currently selected tool ID\n * @property {(tool: string) => void} setSelectedTool - Update selected tool\n * @property {TrackElement | null} selectedElement - Currently selected timeline element\n * @property {(element: TrackElement) => void} addElement - Add element to timeline\n * @property {(element: TrackElement) => void} updateElement - Update existing element\n *\n * @example\n * ```tsx\n * const {\n * selectedTool,\n * setSelectedTool,\n * selectedElement,\n * addElement,\n * updateElement\n * } = useStudioManager();\n * ```\n */\n\nimport { Track, TrackElement, useTimelineContext } from \"@twick/timeline\";\nimport { useEditorManager } from \"@twick/video-editor\";\nimport { useEffect, useRef, useState } from \"react\";\n\nconst SHAPES_TOOLS = [\"rect\", \"circle\", \"line\", \"arrow\"] as string[];\n\nexport const useStudioManager = () => {\n const [selectedProp, setSelectedProp] = useState(\"element-props\");\n\n const { selectedItem } = useTimelineContext();\n\n const { addElement, updateElement } = useEditorManager();\n\n const selectedElement =\n selectedItem instanceof TrackElement ? selectedItem : null;\n\n const [selectedTool, setSelectedTool] = useState<string>(\"none\");\n\n const isToolChanged = useRef(false);\n\n useEffect(() => {\n if (selectedItem instanceof TrackElement) {\n const elementType = selectedItem.getType();\n if(SHAPES_TOOLS.includes(elementType)) {\n setSelectedTool(\"shape\");\n } else {\n setSelectedTool(selectedItem.getType());\n }\n isToolChanged.current = true;\n } else if (selectedItem instanceof Track) {\n // do-nothing\n } else {\n setSelectedTool(\"video\");\n }\n }, [selectedItem]);\n\n return {\n selectedProp,\n setSelectedProp,\n selectedTool,\n setSelectedTool,\n selectedElement,\n addElement,\n updateElement,\n };\n};\n","import { useCallback, useState } from \"react\";\n\nexport type CloudUploadProvider = \"s3\" | \"gcs\";\n\nexport interface UseCloudMediaUploadConfig {\n uploadApiUrl: string;\n provider: CloudUploadProvider;\n}\n\n/** Response from S3 presign API (e.g. file-uploader Lambda). */\nexport interface S3PresignResponse {\n uploadUrl: string;\n key?: string;\n bucket?: string;\n contentType?: string;\n expiresIn?: number;\n}\n\n/** Response from GCS upload API (server-side upload). */\nexport interface GCSUploadResponse {\n url: string;\n}\n\nexport interface UseCloudMediaUploadReturn {\n uploadFile: (file: File) => Promise<{ url: string }>;\n isUploading: boolean;\n progress: number;\n error: string | null;\n resetError: () => void;\n}\n\nconst putFileWithProgress = (\n uploadUrl: string,\n file: File,\n onProgress: (percent: number) => void\n): Promise<void> => {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable) {\n onProgress((e.loaded / e.total) * 100);\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n onProgress(100);\n resolve();\n } else {\n reject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => reject(new Error(\"Upload failed\")));\n xhr.addEventListener(\"abort\", () => reject(new Error(\"Upload aborted\")));\n\n xhr.open(\"PUT\", uploadUrl);\n xhr.setRequestHeader(\"Content-Type\", file.type || \"application/octet-stream\");\n xhr.send(file);\n });\n};\n\nexport const useCloudMediaUpload = (\n config: UseCloudMediaUploadConfig\n): UseCloudMediaUploadReturn => {\n const { uploadApiUrl, provider } = config;\n const [isUploading, setIsUploading] = useState(false);\n const [progress, setProgress] = useState(0);\n const [error, setError] = useState<string | null>(null);\n\n const resetError = useCallback(() => {\n setError(null);\n }, []);\n\n const uploadFile = useCallback(\n async (file: File): Promise<{ url: string }> => {\n setIsUploading(true);\n setProgress(0);\n setError(null);\n\n try {\n if (provider === \"s3\") {\n const presignRes = await fetch(uploadApiUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n filename: file.name,\n contentType: file.type || \"application/octet-stream\",\n }),\n });\n\n if (!presignRes.ok) {\n const errBody = await presignRes.json().catch(() => ({}));\n throw new Error(\n (errBody as { error?: string }).error ??\n `Failed to get upload URL: ${presignRes.statusText}`\n );\n }\n\n const presignData = (await presignRes.json()) as S3PresignResponse;\n const uploadUrl = presignData.uploadUrl;\n\n await putFileWithProgress(uploadUrl, file, setProgress);\n\n const publicUrl = uploadUrl.split(\"?\")[0];\n return { url: publicUrl };\n }\n\n if (provider === \"gcs\") {\n setProgress(10);\n const formData = new FormData();\n formData.append(\"file\", file);\n\n const uploadRes = await fetch(uploadApiUrl, {\n method: \"POST\",\n body: formData,\n });\n\n if (!uploadRes.ok) {\n const errBody = await uploadRes.json().catch(() => ({}));\n throw new Error(\n (errBody as { error?: string }).error ??\n `Upload failed: ${uploadRes.statusText}`\n );\n }\n\n setProgress(100);\n const data = (await uploadRes.json()) as GCSUploadResponse;\n if (!data.url) {\n throw new Error(\"Upload response missing url\");\n }\n return { url: data.url };\n }\n\n throw new Error(`Unknown provider: ${provider}`);\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Upload failed\";\n setError(message);\n throw err;\n } finally {\n setIsUploading(false);\n setProgress(0);\n }\n },\n [uploadApiUrl, provider]\n );\n\n return {\n uploadFile,\n isUploading,\n progress,\n error,\n resetError,\n };\n};\n","import { useRef } from \"react\";\nimport { Upload } from \"lucide-react\";\nimport {\n useCloudMediaUpload,\n type CloudUploadProvider,\n} from \"../../hooks/use-cloud-media-upload\";\n\nexport interface CloudMediaUploadProps {\n onSuccess: (url: string, file: File) => void;\n onError?: (error: string) => void;\n accept?: string;\n uploadApiUrl: string;\n provider: CloudUploadProvider;\n buttonText?: string;\n className?: string;\n disabled?: boolean;\n id?: string;\n icon?: React.ReactNode;\n}\n\nexport const CloudMediaUpload = ({\n onSuccess,\n onError,\n accept,\n uploadApiUrl,\n provider,\n buttonText = \"Upload to cloud\",\n className,\n disabled = false,\n id: providedId,\n icon,\n}: CloudMediaUploadProps) => {\n const id = providedId ?? `cloud-media-upload-${Math.random().toString(36).slice(2, 9)}`;\n const inputRef = useRef<HTMLInputElement>(null);\n\n const {\n uploadFile,\n isUploading,\n progress,\n error,\n resetError,\n } = useCloudMediaUpload({ uploadApiUrl, provider });\n\n const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n\n try {\n const { url } = await uploadFile(file);\n onSuccess(url, file);\n if (inputRef.current) {\n inputRef.current.value = \"\";\n }\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Upload failed\";\n onError?.(message);\n }\n };\n\n const handleLabelClick = () => {\n if (disabled || isUploading) return;\n resetError();\n };\n\n return (\n <div className=\"file-input-container cloud-media-upload-container\">\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n className=\"file-input-hidden\"\n id={id}\n onChange={handleFileChange}\n disabled={disabled || isUploading}\n aria-label={buttonText}\n />\n <label\n htmlFor={id}\n className={className ?? \"btn-primary file-input-label\"}\n onClick={handleLabelClick}\n style={{ pointerEvents: disabled || isUploading ? \"none\" : undefined }}\n >\n {icon ?? <Upload className=\"icon-sm\" />}\n {isUploading ? `${Math.round(progress)}%` : buttonText}\n </label>\n {isUploading && (\n <div className=\"cloud-media-upload-progress\" role=\"progressbar\" aria-valuenow={progress} aria-valuemin={0} aria-valuemax={100}>\n <div\n className=\"cloud-media-upload-progress-fill\"\n style={{ width: `${progress}%` }}\n />\n </div>\n )}\n {error && (\n <div className=\"cloud-media-upload-error\" role=\"alert\">\n {error}\n </div>\n )}\n </div>\n );\n};\n","import { BrowserMediaManager } from \"@twick/video-editor\";\nimport type { MediaItem } from \"@twick/video-editor\";\n\nclass MediaManagerSingleton {\n private static instance: BrowserMediaManager | null = null;\n private static initializationPromise: Promise<void> | null = null;\n private static isInitialized = false;\n\n private constructor() {}\n\n public static getInstance(): BrowserMediaManager {\n if (!MediaManagerSingleton.instance) {\n MediaManagerSingleton.instance = new BrowserMediaManager();\n }\n return MediaManagerSingleton.instance;\n }\n\n public static async initializeDefaults(): Promise<void> {\n // If already initialized, return immediately\n if (MediaManagerSingleton.isInitialized) {\n return;\n }\n\n // If initialization is in progress, wait for it to complete\n if (MediaManagerSingleton.initializationPromise) {\n await MediaManagerSingleton.initializationPromise;\n return;\n }\n\n // Create and store the promise immediately to prevent concurrent initialization\n // This must be synchronous to prevent race conditions\n let resolvePromise: () => void;\n let rejectPromise: (error: any) => void;\n \n MediaManagerSingleton.initializationPromise = new Promise<void>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n });\n\n // Start initialization asynchronously\n (async () => {\n try {\n await MediaManagerSingleton.doInitializeDefaults();\n MediaManagerSingleton.isInitialized = true;\n resolvePromise!();\n } catch (error) {\n MediaManagerSingleton.initializationPromise = null;\n rejectPromise!(error);\n }\n })();\n \n return MediaManagerSingleton.initializationPromise;\n }\n\n private static async doInitializeDefaults(): Promise<void> {\n const manager = MediaManagerSingleton.getInstance();\n \n // Default video URLs\n const defaultVideos = [\n {\n name: \"Mountain Road\",\n url: \"https://videos.pexels.com/video-files/31708803/13510402_1080_1920_30fps.mp4\",\n type: \"video\",\n metadata: {\n name: \"Mountain Road\",\n source: \"pexels\",\n },\n },\n {\n name: \"Vase\",\n url: \"https://videos.pexels.com/video-files/4622990/4622990-uhd_1440_2560_30fps.mp4\",\n type: \"video\",\n metadata: {\n name: \"Vase\",\n source: \"pexels\",\n },\n },\n ] as Omit<MediaItem, \"id\">[];\n\n // Default image URLs\n const defaultImages = [\n {\n name: \"Mountain Road\",\n url: \"https://images.pexels.com/photos/1955134/pexels-photo-1955134.jpeg\",\n type: \"image\",\n metadata: {\n name: \"Mountain Road\",\n source: \"pexels\",\n },\n },\n {\n name: \"Waterfall\",\n url: \"https://images.pexels.com/photos/358457/pexels-photo-358457.jpeg\",\n type: \"image\",\n metadata: {\n name: \"Waterfall\",\n source: \"pexels\",\n },\n },\n ] as Omit<MediaItem, \"id\">[];\n\n // Default audio URLs\n const defaultAudios = [\n {\n name: \"Audio 1\",\n url: \"https://cdn.pixabay.com/audio/2022/03/14/audio_782eeb590e.mp3\",\n type: \"audio\",\n metadata: {\n name: \"Audio 1\",\n source: \"pixabay\",\n },\n },\n {\n name: \"Audio 2\",\n url: \"https://cdn.pixabay.com/audio/2025/01/24/audio_24048c78b6.mp3\",\n type: \"audio\",\n metadata: {\n name: \"Audio 2\",\n source: \"pixabay\",\n },\n },\n ] as Omit<MediaItem, \"id\">[];\n\n try {\n // Check if default videos already exist in the database\n const existingVideos = await manager.search({\n type: \"video\",\n query: \"\",\n });\n\n // Check if we already have the default videos by URL\n const existingVideoUrls = new Set(existingVideos.map((v) => v.url));\n const videosToAdd = defaultVideos.filter(\n (video) => !existingVideoUrls.has(video.url)\n );\n\n // Add default videos if they don't exist (check again right before adding to prevent race conditions)\n if (videosToAdd.length > 0) {\n // Double-check to prevent duplicates in case of race conditions\n const finalCheck = await manager.search({\n type: \"video\",\n query: \"\",\n });\n const finalVideoUrls = new Set(finalCheck.map((v) => v.url));\n const finalVideosToAdd = videosToAdd.filter(\n (video) => !finalVideoUrls.has(video.url)\n );\n \n if (finalVideosToAdd.length > 0) {\n await manager.addItems(finalVideosToAdd);\n }\n }\n\n // Check if default images already exist in the database\n const existingImages = await manager.search({\n type: \"image\",\n query: \"\",\n });\n\n // Check if we already have the default images by URL\n const existingImageUrls = new Set(existingImages.map((img) => img.url));\n const imagesToAdd = defaultImages.filter(\n (image) => !existingImageUrls.has(image.url)\n );\n\n // Add default images if they don't exist (check again right before adding)\n if (imagesToAdd.length > 0) {\n // Double-check to prevent duplicates in case of race conditions\n const finalCheck = await manager.search({\n type: \"image\",\n query: \"\",\n });\n const finalImageUrls = new Set(finalCheck.map((img) => img.url));\n const finalImagesToAdd = imagesToAdd.filter(\n (image) => !finalImageUrls.has(image.url)\n );\n \n if (finalImagesToAdd.length > 0) {\n await manager.addItems(finalImagesToAdd);\n }\n }\n\n // Check if default audio files already exist in the database\n const existingAudios = await manager.search({\n type: \"audio\",\n query: \"\",\n });\n\n // Check if we already have the default audio files by URL\n const existingAudioUrls = new Set(existingAudios.map((a) => a.url));\n const audiosToAdd = defaultAudios.filter(\n (audio) => !existingAudioUrls.has(audio.url)\n );\n\n // Add default audio files if they don't exist (check again right before adding)\n if (audiosToAdd.length > 0) {\n // Double-check to prevent duplicates in case of race conditions\n const finalCheck = await manager.search({\n type: \"audio\",\n query: \"\",\n });\n const finalAudioUrls = new Set(finalCheck.map((a) => a.url));\n const finalAudiosToAdd = audiosToAdd.filter(\n (audio) => !finalAudioUrls.has(audio.url)\n );\n \n if (finalAudiosToAdd.length > 0) {\n await manager.addItems(finalAudiosToAdd);\n }\n }\n } catch (error) {\n // Error is handled in initializeDefaults, just re-throw it\n throw error;\n }\n }\n}\n\n// Export a function to get the singleton instance\nexport const getMediaManager = () => MediaManagerSingleton.getInstance();\n\n// Export a function to initialize default videos\nexport const initializeDefaultVideos = () => MediaManagerSingleton.initializeDefaults(); ","import { useState } from \"react\";\nimport { Plus } from \"lucide-react\";\n\ntype MediaType = \"video\" | \"audio\" | \"image\";\n\nconst EXTENSIONS: Record<MediaType, string[]> = {\n video: [\"mp4\", \"webm\", \"ogg\", \"mov\", \"mkv\", \"m3u8\"],\n audio: [\"mp3\", \"wav\", \"ogg\", \"m4a\", \"aac\", \"flac\"],\n image: [\"jpg\", \"jpeg\", \"png\", \"gif\", \"webp\", \"svg\"],\n};\n\nfunction isValidUrl(url: string) {\n try {\n // eslint-disable-next-line no-new\n new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction matchesType(url: string, type: MediaType) {\n const pathname = (() => {\n try {\n return new URL(url).pathname.toLowerCase();\n } catch {\n return url.toLowerCase();\n }\n })();\n const ext = pathname.split(\".\").pop() || \"\";\n return EXTENSIONS[type].includes(ext);\n}\n\n// (name extraction removed; naming handled by caller if needed)\n\nexport default function UrlInput({\n type,\n onSubmit,\n}: {\n type: MediaType;\n onSubmit: (url: string) => void;\n}) {\n const [url, setUrl] = useState(\"\");\n const [error, setError] = useState<string>(\"\");\n\n const tryAdd = async () => {\n const trimmed = url.trim();\n if (!trimmed) return;\n\n if (!isValidUrl(trimmed)) {\n setError(\"Enter a valid URL\");\n return;\n }\n\n if (!matchesType(trimmed, type)) {\n setError(`URL must be a ${type} (${EXTENSIONS[type].join(\", \")})`);\n return;\n }\n\n setError(\"\");\n\n onSubmit(trimmed);\n setUrl(\"\");\n };\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n void tryAdd();\n }\n };\n\n return (\n <div>\n <div className=\"flex-container\">\n <input\n type=\"url\"\n placeholder={`Paste ${type} URL...`}\n value={url}\n onChange={(e) => setUrl(e.target.value)}\n onKeyDown={onKeyDown}\n className=\"input w-full\"\n />\n <button\n className=\"btn-ghost\"\n onClick={() => void tryAdd()}\n aria-label={`Add ${type} by URL`}\n >\n <Plus size={16} />\n </button>\n </div>\n {error ? <span className=\"text-error\">{error}</span> : null}\n </div>\n );\n}\n","import { createContext, useContext, useEffect, useState, ReactNode } from \"react\";\nimport type { MediaItem } from \"@twick/video-editor\";\nimport { getMediaManager, initializeDefaultVideos } from \"../components/shared\";\n\ntype MediaType = \"video\" | \"audio\" | \"image\";\n\ninterface MediaState {\n items: MediaItem[];\n searchQuery: string;\n isLoading: boolean;\n}\n\ninterface MediaContextType {\n videoState: MediaState;\n audioState: MediaState;\n imageState: MediaState;\n setSearchQuery: (type: MediaType, query: string) => void;\n addItem: (type: MediaType, item: MediaItem) => void;\n}\n\nconst initialMediaState: MediaState = {\n items: [],\n searchQuery: \"\",\n isLoading: false,\n};\n\nconst MediaContext = createContext<MediaContextType | null>(null);\n\nexport function MediaProvider({ children }: { children: ReactNode }) {\n const [videoState, setVideoState] = useState<MediaState>(initialMediaState);\n const [audioState, setAudioState] = useState<MediaState>(initialMediaState);\n const [imageState, setImageState] = useState<MediaState>(initialMediaState);\n const mediaManager = getMediaManager();\n\n const getStateAndSetter = (type: MediaType): [MediaState, (state: MediaState) => void] => {\n switch (type) {\n case \"video\":\n return [videoState, setVideoState];\n case \"audio\":\n return [audioState, setAudioState];\n case \"image\":\n return [imageState, setImageState];\n }\n };\n\n const loadItems = async (type: MediaType, query: string) => {\n const [state, setState] = getStateAndSetter(type);\n \n setState({ ...state, isLoading: true });\n try {\n const results = await mediaManager.search({\n query,\n type,\n });\n setState({\n items: results,\n searchQuery: query,\n isLoading: false,\n });\n } catch (error) {\n console.error(`Error loading ${type} items:`, error);\n setState({\n ...state,\n isLoading: false,\n });\n }\n };\n\n // Initialize default videos and load initial data for each type\n useEffect(() => {\n const initialize = async () => {\n // Initialize default videos first\n await initializeDefaultVideos();\n // Then load all media items\n loadItems(\"video\", \"\");\n loadItems(\"audio\", \"\");\n loadItems(\"image\", \"\");\n };\n initialize();\n }, []);\n\n const setSearchQuery = (type: MediaType, query: string) => {\n const [state, setState] = getStateAndSetter(type);\n setState({ ...state, searchQuery: query });\n loadItems(type, query);\n };\n\n const addItem = (type: MediaType, newItem: MediaItem) => {\n const [state, setState] = getStateAndSetter(type);\n setState({\n ...state,\n items: [...state.items, newItem],\n });\n };\n\n return (\n <MediaContext.Provider\n value={{\n videoState,\n audioState,\n imageState,\n setSearchQuery,\n addItem,\n }}\n >\n {children}\n </MediaContext.Provider>\n );\n}\n\nexport function useMedia(type: MediaType) {\n const context = useContext(MediaContext);\n if (!context) {\n throw new Error(\"useMedia must be used within a MediaProvider\");\n }\n\n const state = context[`${type}State`];\n return {\n items: state.items,\n searchQuery: state.searchQuery,\n isLoading: state.isLoading,\n setSearchQuery: (query: string) => context.setSearchQuery(type, query),\n addItem: (item: MediaItem) => context.addItem(type, item),\n };\n}\n","import {\n TrackElement,\n VideoElement,\n AudioElement,\n ImageElement,\n Size,\n} from \"@twick/timeline\";\nimport type { MediaItem } from \"@twick/video-editor\";\nimport { getMediaManager } from \"../components/shared\";\nimport { useMedia } from \"../context/media-context\";\n\nexport interface MediaPanelState {\n items: MediaItem[];\n searchQuery: string;\n isLoading: boolean;\n acceptFileTypes: string[];\n}\n\nexport interface MediaPanelActions {\n setSearchQuery: (query: string) => void;\n handleSelection: (item: MediaItem, forceAdd?: boolean) => void;\n handleFileUpload: (fileData: { file: File; blobUrl: string }) => void;\n}\n\nexport type MediaType = \"video\" | \"audio\" | \"image\";\n\nconst mediaConfigs = {\n video: {\n acceptFileTypes: [\"video/*\"] as string[],\n createElement: (url: string, parentSize: Size) =>\n new VideoElement(url, parentSize),\n updateElement: async (element: TrackElement, url: string) => {\n if (element instanceof VideoElement) {\n element.setSrc(url);\n await element.updateVideoMeta();\n }\n },\n },\n audio: {\n acceptFileTypes: [\"audio/*\"] as string[],\n createElement: (url: string, _parentSize: Size) => new AudioElement(url),\n updateElement: async (element: TrackElement, url: string) => {\n if (element instanceof AudioElement) {\n element.setSrc(url);\n await element.updateAudioMeta();\n }\n },\n },\n image: {\n acceptFileTypes: [\"image/*\"] as string[],\n createElement: (url: string, parentSize: Size) =>\n new ImageElement(url, parentSize),\n updateElement: async (element: TrackElement, url: string) => {\n if (element instanceof ImageElement) {\n element.setSrc(url);\n await element.updateImageMeta();\n }\n },\n },\n};\n\nexport const useMediaPanel = (\n type: MediaType,\n {\n selectedElement,\n addElement,\n updateElement,\n }: {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n },\n videoResolution: Size\n): MediaPanelState & MediaPanelActions => {\n const { items, searchQuery, setSearchQuery, addItem, isLoading } =\n useMedia(type);\n const mediaManager = getMediaManager();\n\n const handleSelection = async (item: MediaItem, forceAdd?: boolean) => {\n const config = mediaConfigs[type];\n if (forceAdd) {\n const element = config.createElement(item.url, videoResolution);\n addElement(element);\n } else {\n if (selectedElement) {\n await config.updateElement(selectedElement, item.url);\n updateElement(selectedElement);\n } else {\n const element = config.createElement(item.url, videoResolution);\n addElement(element);\n }\n }\n };\n\n const handleFileUpload = async (fileData: {\n file: File;\n blobUrl: string;\n }) => {\n const arrayBuffer = await fileData.file.arrayBuffer();\n const newItem = await mediaManager.addItem({\n name: fileData.file.name,\n url: fileData.blobUrl,\n type,\n arrayBuffer,\n metadata: {\n name: fileData.file.name,\n size: fileData.file.size,\n type: fileData.file.type,\n },\n });\n addItem(newItem);\n };\n\n const config = mediaConfigs[type];\n return {\n items,\n searchQuery,\n setSearchQuery,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes: config.acceptFileTypes,\n };\n};\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport type { MediaItem } from '@twick/video-editor';\n\nexport interface AudioPreviewState {\n playingAudio: string | null; // ID of currently playing audio\n audioElement: HTMLAudioElement | null;\n}\n\nexport interface AudioPreviewActions {\n togglePlayPause: (item: MediaItem) => void;\n stopPlayback: () => void;\n}\n\nexport const useAudioPreview = (): AudioPreviewState & AudioPreviewActions => {\n const [playingAudio, setPlayingAudio] = useState<string | null>(null);\n const audioRef = useRef<HTMLAudioElement | null>(null);\n\n // Cleanup audio element on unmount\n useEffect(() => {\n return () => {\n if (audioRef.current) {\n audioRef.current.pause();\n audioRef.current = null;\n }\n };\n }, []);\n\n const stopPlayback = useCallback(() => {\n if (audioRef.current) {\n audioRef.current.pause();\n audioRef.current = null;\n }\n setPlayingAudio(null);\n }, []);\n\n const togglePlayPause = useCallback((item: MediaItem) => {\n // If we're already playing this audio, stop it\n if (playingAudio === item.id) {\n stopPlayback();\n return;\n }\n\n // Stop any currently playing audio\n stopPlayback();\n\n // Start playing the new audio\n const audio = new Audio(item.url);\n audio.addEventListener('ended', stopPlayback);\n audio.play();\n audioRef.current = audio;\n setPlayingAudio(item.id);\n }, [playingAudio, stopPlayback]);\n\n return {\n playingAudio,\n audioElement: audioRef.current,\n togglePlayPause,\n stopPlayback,\n };\n};\n","/**\n * AudioPanel Component\n * \n * A panel for managing audio elements in the studio. Provides functionality\n * for searching, uploading, previewing, and adding audio files to the timeline.\n * \n * @component\n * @param {Object} props\n * @param {MediaItem[]} props.items - List of audio items to display\n * @param {string} props.searchQuery - Current search query\n * @param {string | null} props.playingAudio - ID of currently playing audio, if any\n * @param {(query: string) => void} props.onSearchChange - Handle search query changes\n * @param {(item: MediaItem) => void} props.onItemSelect - Handle audio item selection\n * @param {(item: MediaItem) => void} props.onPlayPause - Toggle audio preview playback\n * @param {(data: { file: File; blobUrl: string }) => void} props.onFileUpload - Handle file uploads\n * \n * @example\n * ```tsx\n * <AudioPanel\n * items={audioItems}\n * searchQuery=\"\"\n * playingAudio={null}\n * onSearchChange={setSearchQuery}\n * onItemSelect={handleSelect}\n * onPlayPause={togglePlayback}\n * onFileUpload={handleUpload}\n * />\n * ```\n */\n\nimport { Wand2, Plus, Volume2, Play, Pause } from \"lucide-react\";\nimport { TIMELINE_DROP_MEDIA_TYPE } from \"@twick/video-editor\";\nimport UrlInput from \"../shared/url-input\";\nimport type { AudioPanelProps } from \"../../types/media-panel\";\nimport { useAudioPreview } from \"../../hooks/use-audio-preview\";\n\n\nexport const AudioPanel = ({\n items,\n onItemSelect,\n onUrlAdd,\n isLoading,\n canLoadMore,\n onLoadMore,\n}: AudioPanelProps) => {\n const { playingAudio, togglePlayPause } = useAudioPreview();\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Audio Library</div>\n\n {/* Add by URL */}\n <div className=\"panel-section\">\n <UrlInput type=\"audio\" onSubmit={onUrlAdd} />\n </div>\n\n {/* Audio List */}\n <div className=\"media-content\">\n <div className=\"media-list\">\n {(items || []).map((item) => (\n <div\n key={item.id}\n draggable\n onDoubleClick={() => onItemSelect(item)}\n onDragStart={(e) => {\n e.dataTransfer.setData(\n TIMELINE_DROP_MEDIA_TYPE,\n JSON.stringify({ type: \"audio\", url: item.url })\n );\n e.dataTransfer.effectAllowed = \"copy\";\n }}\n className=\"media-list-item media-item-draggable\"\n >\n {/* Audio Info */}\n <div className=\"media-list-content\">\n {/* Play/Pause button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n togglePlayPause(item);\n }}\n className=\"media-action-btn\"\n >\n {playingAudio === item.id ? (\n <Pause className=\"icon-sm\" />\n ) : (\n <Play className=\"icon-sm\" />\n )}\n </button>\n\n {/* Audio Icon */}\n <div className={`media-list-icon ${playingAudio === item.id ? 'active' : ''}`}>\n <Volume2 className=\"icon-sm\" />\n </div>\n\n {/* Audio Title */}\n <div className=\"media-list-title\">\n {item.metadata?.title || item.metadata?.name}\n </div>\n\n {/* Quick Add button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n onItemSelect(item, true);\n }}\n className=\"media-action-btn\"\n >\n <Plus className=\"icon-sm\" />\n </button>\n </div>\n </div>\n ))}\n </div>\n\n {/* Empty state */}\n {items.length === 0 && (\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Wand2 className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">No audio files found</p>\n </div>\n </div>\n )}\n\n {onLoadMore && canLoadMore && (\n <div className=\"panel-section\">\n <button\n type=\"button\"\n className=\"btn-ghost w-full\"\n onClick={onLoadMore}\n disabled={isLoading}\n >\n {isLoading ? \"Loading...\" : \"Load more\"}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n};","import { Search } from \"lucide-react\";\n\nconst SearchInput = ({\n searchQuery,\n setSearchQuery,\n}: {\n searchQuery: string;\n setSearchQuery: (query: string) => void;\n}) => {\n return (\n <div className=\"search-container\">\n <input\n type=\"text\"\n placeholder=\"Search media...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"input search-input w-full\"\n />\n <Search className=\"search-icon\" />\n </div>\n );\n};\n\nexport default SearchInput;\n","import type {\n AssetLibrary,\n AssetListParams,\n AssetProviderConfig,\n MediaItem,\n} from \"@twick/video-editor\";\nimport { getMediaManager } from \"../components/shared\";\n\ninterface Paginated<T> {\n items: T[];\n page: number;\n pageSize: number;\n total: number;\n}\n\nconst DEFAULT_PAGE_SIZE = 50;\n\nasync function listUserAssets(params: AssetListParams): Promise<Paginated<MediaItem>> {\n const mediaManager = getMediaManager();\n const all = await mediaManager.search({\n query: params.query,\n type: params.type,\n });\n\n const page = params.page ?? 1;\n const pageSize = params.pageSize ?? DEFAULT_PAGE_SIZE;\n const start = (page - 1) * pageSize;\n const end = start + pageSize;\n\n return {\n items: all.slice(start, end),\n page,\n pageSize,\n total: all.length,\n };\n}\n\nasync function listPublicAssets(params: AssetListParams): Promise<Paginated<MediaItem>> {\n const page = params.page ?? 1;\n const pageSize = params.pageSize ?? DEFAULT_PAGE_SIZE;\n\n const searchParams = new URLSearchParams();\n searchParams.set(\"source\", \"public\");\n if (params.type) searchParams.set(\"type\", params.type);\n if (params.query) searchParams.set(\"query\", params.query);\n if (params.provider) searchParams.set(\"provider\", params.provider);\n searchParams.set(\"page\", String(page));\n searchParams.set(\"pageSize\", String(pageSize));\n\n const res = await fetch(`/api/assets/search?${searchParams.toString()}`);\n if (!res.ok) {\n throw new Error(`Failed to search public assets (${res.status})`);\n }\n\n const data = (await res.json()) as Paginated<any>;\n\n const items: MediaItem[] = (data.items || []).map((asset: any) => ({\n id: asset.id,\n name: asset.name,\n type: asset.type,\n url: asset.url,\n previewUrl: asset.previewUrl,\n thumbnail: asset.previewUrl ?? asset.thumbnail,\n waveformUrl: asset.waveformUrl,\n duration: asset.duration,\n width: asset.width,\n height: asset.height,\n sizeBytes: asset.sizeBytes,\n source: asset.source,\n origin: asset.origin,\n provider: asset.provider,\n providerId: asset.providerId,\n providerUrl: asset.providerUrl,\n attribution: asset.attribution,\n tags: asset.tags,\n metadata: asset.metadata,\n }));\n\n return {\n items,\n page: data.page ?? page,\n pageSize: data.pageSize ?? pageSize,\n total: data.total ?? items.length,\n };\n}\n\nconst studioAssetLibrary: AssetLibrary = {\n async listAssets(params: AssetListParams): Promise<Paginated<MediaItem>> {\n if (params.source === \"user\") {\n return listUserAssets(params);\n }\n return listPublicAssets(params);\n },\n\n async getAsset(id: string): Promise<MediaItem | null> {\n const mediaManager = getMediaManager();\n const item = await mediaManager.getItem(id);\n return item ?? null;\n },\n\n async uploadAsset(\n file: File,\n options?: {\n type?: \"video\" | \"audio\" | \"image\";\n metadata?: Record<string, unknown>;\n }\n ): Promise<MediaItem> {\n const mediaManager = getMediaManager();\n const arrayBuffer = await file.arrayBuffer();\n const type = options?.type ?? file.type.split(\"/\")[0];\n\n const item = await mediaManager.addItem({\n name: file.name,\n url: URL.createObjectURL(new Blob([arrayBuffer], { type: file.type })),\n type,\n arrayBuffer,\n metadata: {\n ...(options?.metadata ?? {}),\n name: file.name,\n size: file.size,\n type: file.type,\n source: \"upload\",\n },\n });\n\n return item;\n },\n\n async deleteAsset(id: string): Promise<void> {\n const mediaManager = getMediaManager();\n await mediaManager.deleteItem(id);\n },\n\n async listPublicProviders(): Promise<AssetProviderConfig[]> {\n const res = await fetch(\"/api/assets/providers/config\");\n if (!res.ok) {\n throw new Error(`Failed to load asset providers (${res.status})`);\n }\n const data = (await res.json()) as { providers?: AssetProviderConfig[] };\n return data.providers ?? [];\n },\n};\n\nexport const getAssetLibrary = () => studioAssetLibrary;\n\n","import { useEffect, useMemo, useState } from \"react\";\nimport { useMediaPanel } from \"../../hooks/use-media-panel\";\nimport { AudioPanel } from \"../panel/audio-panel\";\nimport type { PanelProps } from \"../../types\";\nimport { useMedia } from \"../../context/media-context\";\nimport { getMediaManager, CloudMediaUpload } from \"../shared\";\nimport SearchInput from \"../shared/search-input\";\nimport type { AssetProviderConfig, MediaItem } from \"@twick/video-editor\";\nimport { getAssetLibrary } from \"../../helpers/asset-library\";\nimport { throttle } from \"@twick/video-editor\";\n\nexport const AudioPanelContainer = (props: PanelProps) => {\n const [activeSource, setActiveSource] = useState<\"user\" | \"public\">(\"user\");\n\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n className={`btn-ghost w-full ${activeSource === \"user\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"user\")}\n >\n My assets\n </button>\n <button\n type=\"button\"\n className={`btn-ghost w-full ${activeSource === \"public\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"public\")}\n >\n Public\n </button>\n </div>\n </div>\n\n {activeSource === \"user\" ? (\n <AudioUserAssetsSection {...props} />\n ) : (\n <AudioPublicAssetsSection />\n )}\n </>\n );\n};\n\nfunction AudioUserAssetsSection(props: PanelProps) {\n const { addItem } = useMedia(\"audio\");\n const mediaManager = getMediaManager();\n const {\n items,\n searchQuery,\n setSearchQuery,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes,\n } = useMediaPanel(\n \"audio\",\n {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution,\n );\n\n const onUrlAdd = async (url: string) => {\n const nameFromUrl = (() => {\n try {\n const u = new URL(url);\n const parts = u.pathname.split(\"/\").filter(Boolean);\n return decodeURIComponent(parts[parts.length - 1] || url);\n } catch {\n return url;\n }\n })();\n\n const newItem = await mediaManager.addItem({\n name: nameFromUrl,\n url,\n type: \"audio\",\n metadata: { source: \"url\" },\n });\n addItem(newItem);\n };\n\n const onCloudUploadSuccess = async (url: string, file: File) => {\n const newItem = await mediaManager.addItem({\n name: file.name,\n url,\n type: \"audio\",\n metadata: { source: props.uploadConfig?.provider ?? \"s3\" },\n });\n addItem(newItem);\n };\n\n return (\n <>\n {props.uploadConfig && (\n <div className=\"flex panel-section\">\n <CloudMediaUpload\n uploadApiUrl={props.uploadConfig.uploadApiUrl}\n provider={props.uploadConfig.provider}\n accept=\"audio/*\"\n onSuccess={onCloudUploadSuccess}\n buttonText=\"Upload audio\"\n className=\"btn-ghost w-full\"\n />\n </div>\n )}\n <AudioPanel\n items={items}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onItemSelect={handleSelection}\n onFileUpload={handleFileUpload}\n isLoading={isLoading}\n acceptFileTypes={acceptFileTypes}\n onUrlAdd={onUrlAdd}\n />\n </>\n );\n}\n\nfunction AudioPublicAssetsSection() {\n const assetLibrary = getAssetLibrary();\n const [providerConfigs, setProviderConfigs] = useState<AssetProviderConfig[]>(\n [],\n );\n const [activeProviderId, setActiveProviderId] = useState<string | \"all\">(\n \"all\",\n );\n const [publicItems, setPublicItems] = useState<MediaItem[]>([]);\n const [publicSearchQuery, setPublicSearchQuery] = useState(\"\");\n const [isPublicLoading, setIsPublicLoading] = useState(false);\n\n useEffect(() => {\n const loadProviders = async () => {\n try {\n const configs = await assetLibrary.listPublicProviders();\n // Only show providers that actually support audio\n setProviderConfigs(\n configs.filter((c) => c.supportedTypes?.includes(\"audio\")),\n );\n } catch (err) {\n console.error(\"Failed to load asset providers\", err);\n }\n };\n void loadProviders();\n }, [assetLibrary]);\n\n const loadPublicAssets = async (query: string) => {\n setIsPublicLoading(true);\n try {\n const result = await assetLibrary.listAssets({\n source: \"public\",\n type: \"audio\",\n query,\n provider: activeProviderId === \"all\" ? undefined : activeProviderId,\n });\n setPublicItems(result.items);\n } catch (err) {\n console.error(\"Failed to load public audio assets\", err);\n setPublicItems([]);\n } finally {\n setIsPublicLoading(false);\n }\n };\n\n const throttledLoadPublicAssets = useMemo(\n () => throttle(loadPublicAssets, 1000),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [assetLibrary, activeProviderId],\n );\n\n useEffect(() => {\n if (publicSearchQuery) {\n void throttledLoadPublicAssets(publicSearchQuery);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeProviderId, publicSearchQuery]);\n\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"property-row\">\n <div className=\"property-row-label\">\n <span className=\"property-label\">Provider</span>\n </div>\n <div className=\"property-row-control\">\n <select\n className=\"select-dark\"\n value={activeProviderId}\n onChange={(e) =>\n setActiveProviderId(e.target.value as string | \"all\")\n }\n >\n <option value=\"all\">All providers</option>\n {providerConfigs\n .filter((p) => p.enabled)\n .map((p) => (\n <option key={p.id} value={p.id}>\n {p.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"property-row-control\">\n <SearchInput\n searchQuery={publicSearchQuery}\n setSearchQuery={(q) => {\n setPublicSearchQuery(q);\n }}\n />\n </div>\n </div>\n <AudioPanel\n items={publicItems}\n searchQuery={publicSearchQuery}\n onSearchChange={setPublicSearchQuery}\n onItemSelect={() => { }}\n onFileUpload={() => { }}\n isLoading={isPublicLoading}\n acceptFileTypes={[]}\n onUrlAdd={() => { }}\n />\n </>\n );\n}\n","/**\n * ImagePanel Component\n *\n * A panel for managing image elements in the studio. Provides functionality\n * for searching, uploading, previewing, and adding image files to the timeline.\n * Features a grid layout with image thumbnails and hover actions.\n *\n * @component\n * @param {Object} props\n * @param {MediaItem[]} props.items - List of image items to display\n * @param {string} props.searchQuery - Current search query\n * @param {(query: string) => void} props.setSearchQuery - Handle search query changes\n * @param {(item: MediaItem) => void} props.handleSelection - Handle image item selection\n * @param {(data: { file: File; blobUrl: string }) => void} props.handleFileUpload - Handle file uploads\n *\n * @example\n * ```tsx\n * <ImagePanel\n * items={imageItems}\n * searchQuery=\"\"\n * setSearchQuery={setSearchQuery}\n * handleSelection={handleSelect}\n * handleFileUpload={handleUpload}\n * />\n * ```\n */\n\nimport { Wand2, Plus } from \"lucide-react\";\nimport type { MediaItem } from \"@twick/video-editor\";\nimport { TIMELINE_DROP_MEDIA_TYPE } from \"@twick/video-editor\";\nimport type { ImagePanelProps } from \"../../types/media-panel\";\nimport UrlInput from \"../shared/url-input\";\n\nexport function ImagePanel({\n items,\n onItemSelect,\n onUrlAdd,\n isLoading,\n canLoadMore,\n onLoadMore,\n showAddByUrl = true,\n}: ImagePanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Image Library</div>\n\n {/* Add by URL */}\n {showAddByUrl && (\n <div className=\"panel-section\">\n <UrlInput type=\"image\" onSubmit={onUrlAdd} />\n </div>\n )}\n\n {/* Media Grid */}\n <div className=\"media-content\">\n <div className=\"media-grid\">\n {(items || []).map((item: MediaItem) => (\n <div\n key={item.id}\n draggable\n onDoubleClick={() => onItemSelect(item)}\n onDragStart={(e) => {\n e.dataTransfer.setData(\n TIMELINE_DROP_MEDIA_TYPE,\n JSON.stringify({ type: \"image\", url: item.url })\n );\n e.dataTransfer.effectAllowed = \"copy\";\n }}\n className=\"media-item media-item-draggable\"\n >\n <img src={item.url} alt=\"\" className=\"media-item-content\" />\n <div className=\"media-actions media-actions-corner\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n onItemSelect(item, true);\n }}\n className=\"media-action-btn\"\n >\n <Plus className=\"icon-sm\" />\n </button>\n </div>\n </div>\n ))}\n </div>\n\n {/* Empty state */}\n {items.length === 0 && (\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Wand2 className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">No images found</p>\n </div>\n </div>\n )}\n\n {onLoadMore && canLoadMore && (\n <div className=\"panel-section\">\n <button\n type=\"button\"\n className=\"btn-ghost w-full\"\n onClick={onLoadMore}\n disabled={isLoading}\n >\n {isLoading ? \"Loading...\" : \"Load more\"}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport type { PanelProps } from \"../../types\";\nimport { ImagePanel } from \"../panel/image-panel\";\nimport { useMediaPanel } from \"../../hooks/use-media-panel\";\nimport { useMedia } from \"../../context/media-context\";\nimport { getMediaManager, CloudMediaUpload } from \"../shared\";\nimport SearchInput from \"../shared/search-input\";\nimport { throttle, type AssetProviderConfig, type MediaItem } from \"@twick/video-editor\";\nimport { getAssetLibrary } from \"../../helpers/asset-library\";\n\nexport function ImagePanelContainer(props: PanelProps) {\n const [activeSource, setActiveSource] = useState<\"user\" | \"public\">(\"user\");\n\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n className={`btn-ghost w-full ${\n activeSource === \"user\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"user\")}\n >\n My assets\n </button>\n <button\n type=\"button\"\n className={`btn-ghost w-full ${\n activeSource === \"public\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"public\")}\n >\n Public\n </button>\n </div>\n </div>\n\n {activeSource === \"user\" ? (\n <ImageUserAssetsSection {...props} />\n ) : (\n <ImagePublicAssetsSection />\n )}\n </>\n );\n}\n\nfunction ImageUserAssetsSection(props: PanelProps) {\n const { addItem } = useMedia(\"image\");\n const mediaManager = getMediaManager();\n const [page, setPage] = useState(1);\n const PAGE_SIZE = 30;\n const {\n items,\n searchQuery,\n setSearchQuery,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes,\n } = useMediaPanel(\n \"image\",\n {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution,\n );\n\n const onUrlAdd = async (url: string) => {\n const nameFromUrl = (() => {\n try {\n const u = new URL(url);\n const parts = u.pathname.split(\"/\").filter(Boolean);\n return decodeURIComponent(parts[parts.length - 1] || url);\n } catch {\n return url;\n }\n })();\n\n const newItem = await mediaManager.addItem({\n name: nameFromUrl,\n url,\n type: \"image\",\n metadata: { source: \"url\" },\n });\n addItem(newItem);\n };\n\n const onCloudUploadSuccess = async (url: string, file: File) => {\n const newItem = await mediaManager.addItem({\n name: file.name,\n url,\n type: \"image\",\n metadata: { source: props.uploadConfig?.provider ?? \"s3\" },\n });\n addItem(newItem);\n };\n\n const visibleItems = items.slice(0, page * PAGE_SIZE);\n const canLoadMore = items.length > visibleItems.length;\n\n useEffect(() => {\n setPage(1);\n }, [searchQuery]);\n\n return (\n <>\n {props.uploadConfig && (\n <div className=\"flex panel-section\">\n <CloudMediaUpload\n uploadApiUrl={props.uploadConfig.uploadApiUrl}\n provider={props.uploadConfig.provider}\n accept=\"image/*\"\n onSuccess={onCloudUploadSuccess}\n buttonText=\"Upload image\"\n className=\"btn-ghost w-full\"\n />\n </div>\n )}\n <ImagePanel\n items={visibleItems}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onItemSelect={handleSelection}\n onFileUpload={handleFileUpload}\n isLoading={isLoading}\n acceptFileTypes={acceptFileTypes}\n onUrlAdd={onUrlAdd}\n canLoadMore={canLoadMore}\n onLoadMore={() => setPage((prev) => prev + 1)}\n />\n </>\n );\n}\n\nfunction ImagePublicAssetsSection() {\n const assetLibrary = getAssetLibrary();\n const [providerConfigs, setProviderConfigs] = useState<AssetProviderConfig[]>(\n [],\n );\n const [activeProviderId, setActiveProviderId] = useState<string | \"all\">(\n \"all\",\n );\n const [publicItems, setPublicItems] = useState<MediaItem[]>([]);\n const [publicSearchQuery, setPublicSearchQuery] = useState(\"nature\");\n const [isPublicLoading, setIsPublicLoading] = useState(false);\n const [page, setPage] = useState(1);\n const [hasMore, setHasMore] = useState(true);\n const PAGE_SIZE = 20;\n\n useEffect(() => {\n const loadProviders = async () => {\n try {\n const configs = await assetLibrary.listPublicProviders();\n // Only show providers that actually support images\n setProviderConfigs(\n configs.filter((c) => c.supportedTypes?.includes(\"image\")),\n );\n } catch (err) {\n console.error(\"Failed to load asset providers\", err);\n }\n };\n void loadProviders();\n }, [assetLibrary]);\n\n const loadPublicAssets = async (query: string) => {\n setIsPublicLoading(true);\n try {\n const result = await assetLibrary.listAssets({\n source: \"public\",\n type: \"image\",\n query,\n provider: activeProviderId === \"all\" ? undefined : activeProviderId,\n page: 1,\n pageSize: PAGE_SIZE,\n });\n setPublicItems(result.items);\n setPage(1);\n setHasMore(result.items.length === PAGE_SIZE);\n } catch (err) {\n console.error(\"Failed to load public image assets\", err);\n setPublicItems([]);\n } finally {\n setIsPublicLoading(false);\n }\n };\n\n const throttledLoadPublicAssets = useMemo(\n () => throttle(loadPublicAssets, 1000),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [assetLibrary, activeProviderId],\n );\n\n useEffect(() => {\n if (publicSearchQuery) {\n void throttledLoadPublicAssets(publicSearchQuery);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeProviderId, publicSearchQuery]);\n\n const loadMore = async () => {\n if (!hasMore || isPublicLoading) return;\n const nextPage = page + 1;\n setIsPublicLoading(true);\n try {\n const result = await assetLibrary.listAssets({\n source: \"public\",\n type: \"image\",\n query: publicSearchQuery,\n provider: activeProviderId === \"all\" ? undefined : activeProviderId,\n page: nextPage,\n pageSize: PAGE_SIZE,\n });\n setPublicItems((prev) => [...prev, ...result.items]);\n setPage(nextPage);\n setHasMore(result.items.length === PAGE_SIZE);\n } catch (err) {\n console.error(\"Failed to load more public image assets\", err);\n } finally {\n setIsPublicLoading(false);\n }\n };\n\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"property-row\">\n <div className=\"property-row-label\">\n <span className=\"property-label\">Provider</span>\n </div>\n <div className=\"property-row-control\">\n <select\n className=\"select-dark\"\n value={activeProviderId}\n onChange={(e) =>\n setActiveProviderId(e.target.value as string | \"all\")\n }\n >\n <option value=\"all\">All providers</option>\n {providerConfigs\n .filter((p) => p.enabled)\n .map((p) => (\n <option key={p.id} value={p.id}>\n {p.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"property-row-control\">\n <SearchInput\n searchQuery={publicSearchQuery}\n setSearchQuery={(q) => {\n setPublicSearchQuery(q);\n }}\n />\n </div>\n </div>\n <ImagePanel\n items={publicItems}\n searchQuery={publicSearchQuery}\n onSearchChange={setPublicSearchQuery}\n onItemSelect={() => {}}\n onFileUpload={() => {}}\n isLoading={isPublicLoading}\n acceptFileTypes={[]}\n onUrlAdd={() => {}}\n showAddByUrl={false}\n canLoadMore={hasMore}\n onLoadMore={loadMore}\n />\n </>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport type { MediaItem } from '@twick/video-editor';\n\nexport interface VideoPreviewState {\n playingVideo: string | null; // ID of currently playing video\n videoElement: HTMLVideoElement | null;\n}\n\nexport interface VideoPreviewActions {\n togglePlayPause: (item: MediaItem, videoElement: HTMLVideoElement) => void;\n stopPlayback: () => void;\n}\n\nexport const useVideoPreview = (): VideoPreviewState & VideoPreviewActions => {\n const [playingVideo, setPlayingVideo] = useState<string | null>(null);\n const videoRef = useRef<HTMLVideoElement | null>(null);\n\n // Cleanup video element on unmount\n useEffect(() => {\n return () => {\n if (videoRef.current) {\n videoRef.current.pause();\n videoRef.current = null;\n }\n };\n }, []);\n\n const stopPlayback = useCallback(() => {\n if (videoRef.current) {\n videoRef.current.pause();\n videoRef.current = null;\n }\n setPlayingVideo(null);\n }, []);\n\n const togglePlayPause = useCallback((item: MediaItem, videoElement: HTMLVideoElement) => {\n // If we're already playing this video, pause it\n if (playingVideo === item.id) {\n videoElement.pause();\n stopPlayback();\n return;\n }\n\n // Stop any currently playing video\n stopPlayback();\n\n // Start playing the new video\n videoElement.currentTime = 0; // Reset to start\n videoElement.play();\n videoRef.current = videoElement;\n setPlayingVideo(item.id);\n\n // Add ended event listener\n videoElement.addEventListener('ended', stopPlayback, { once: true });\n }, [playingVideo, stopPlayback]);\n\n return {\n playingVideo,\n videoElement: videoRef.current,\n togglePlayPause,\n stopPlayback,\n };\n};","/**\n * VideoPanel Component\n * \n * A panel for managing video elements in the studio. Provides functionality\n * for searching, uploading, previewing, and adding video files to the timeline.\n * Features a grid layout with video thumbnails and hover actions.\n * \n * @component\n * @param {Object} props\n * @param {MediaItem[]} props.items - List of video items to display\n * @param {string} props.searchQuery - Current search query\n * @param {(query: string) => void} props.setSearchQuery - Handle search query changes\n * @param {(item: MediaItem) => void} props.handleSelection - Handle video item selection\n * @param {(data: { file: File; blobUrl: string }) => void} props.handleFileUpload - Handle file uploads\n * \n * @example\n * ```tsx\n * <VideoPanel\n * items={videoItems}\n * searchQuery=\"\"\n * setSearchQuery={setSearchQuery}\n * handleSelection={handleSelect}\n * handleFileUpload={handleUpload}\n * />\n * ```\n */\n\nimport { Wand2, Plus, Play, Pause } from \"lucide-react\";\nimport type { MediaItem } from \"@twick/video-editor\";\nimport { TIMELINE_DROP_MEDIA_TYPE } from \"@twick/video-editor\";\nimport type { VideoPanelProps } from \"../../types/media-panel\";\nimport { useVideoPreview } from \"../../hooks/use-video-preview\";\nimport UrlInput from \"../shared/url-input\";\n\n\nexport function VideoPanel({\n items,\n onItemSelect,\n onUrlAdd,\n showAddByUrl = true,\n isLoading,\n canLoadMore,\n onLoadMore,\n}: VideoPanelProps) {\n const { playingVideo, togglePlayPause } = useVideoPreview();\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Video Library</div>\n \n {/* Add by URL */}\n {showAddByUrl && (\n <div className=\"flex panel-section\">\n <UrlInput type=\"video\" onSubmit={onUrlAdd} />\n </div>\n )}\n\n {/* Media Grid */}\n <div className=\"media-content\">\n <div className=\"media-grid\">\n {(items || []).map((item: MediaItem) => (\n <div\n key={item.id}\n draggable\n onDoubleClick={() => onItemSelect(item)}\n onDragStart={(e) => {\n e.dataTransfer.setData(\n TIMELINE_DROP_MEDIA_TYPE,\n JSON.stringify({ type: \"video\", url: item.url })\n );\n e.dataTransfer.effectAllowed = \"copy\";\n }}\n className=\"media-item media-item-draggable\"\n >\n <video\n src={item.url}\n poster={item.thumbnail}\n className=\"media-item-content\"\n ref={(el) => {\n if (el) {\n el.addEventListener('ended', () => {\n el.currentTime = 0;\n }, { once: true });\n }\n }}\n />\n\n {/* Duration */}\n {/* <div className=\"media-duration\">\n 0:13\n </div> */}\n\n {/* Corner play/pause control */}\n <div className=\"media-actions media-actions-corner\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n const videoEl =\n e.currentTarget.parentElement?.parentElement?.querySelector(\"video\");\n if (videoEl) {\n togglePlayPause(item, videoEl);\n }\n }}\n className=\"media-action-btn\"\n >\n {playingVideo === item.id ? (\n <Pause className=\"icon-sm\" />\n ) : (\n <Play className=\"icon-sm\" />\n )}\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n onItemSelect(item, true);\n }}\n className=\"media-action-btn\"\n >\n <Plus className=\"icon-sm\" />\n </button>\n </div>\n </div>\n ))}\n </div>\n\n {/* Empty state */}\n {items.length === 0 && (\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Wand2 className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">No videos found</p>\n </div>\n </div>\n )}\n\n {onLoadMore && canLoadMore && (\n <div className=\"panel-section\">\n <button\n type=\"button\"\n className=\"btn-ghost w-full\"\n onClick={onLoadMore}\n disabled={isLoading}\n >\n {isLoading ? \"Loading...\" : \"Load more\"}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}","import { useEffect, useMemo, useState } from \"react\";\nimport type { PanelProps } from \"../../types\";\nimport { VideoPanel } from \"../panel/video-panel\";\nimport { useMediaPanel } from \"../../hooks/use-media-panel\";\nimport { useMedia } from \"../../context/media-context\";\nimport { getMediaManager, CloudMediaUpload } from \"../shared\";\nimport SearchInput from \"../shared/search-input\";\nimport type { AssetProviderConfig, MediaItem } from \"@twick/video-editor\";\nimport { throttle } from \"@twick/video-editor\";\nimport { getAssetLibrary } from \"../../helpers/asset-library\";\n\nexport function VideoPanelContainer(props: PanelProps) {\n const [activeSource, setActiveSource] = useState<\"user\" | \"public\">(\"user\");\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n className={`btn-ghost w-full ${activeSource === \"user\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"user\")}\n >\n My assets\n </button>\n <button\n type=\"button\"\n className={`btn-ghost w-full ${activeSource === \"public\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"public\")}\n >\n Public\n </button>\n </div>\n </div>\n\n {activeSource === \"user\" ? (\n <VideoUserAssetsSection {...props} />\n ) : (\n <VideoPublicAssetsSection />\n )}\n </>\n );\n}\n\nfunction VideoUserAssetsSection(props: PanelProps) {\n const { addItem } = useMedia(\"video\");\n const mediaManager = getMediaManager();\n const [page, setPage] = useState(1);\n const PAGE_SIZE = 30;\n const {\n items,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes,\n } = useMediaPanel(\n \"video\",\n {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution,\n );\n\n const onUrlAdd = async (url: string) => {\n const nameFromUrl = (() => {\n try {\n const u = new URL(url);\n const parts = u.pathname.split(\"/\").filter(Boolean);\n return decodeURIComponent(parts[parts.length - 1] || url);\n } catch {\n return url;\n }\n })();\n\n const newItem = await mediaManager.addItem({\n name: nameFromUrl,\n url,\n type: \"video\",\n metadata: { source: \"url\" },\n });\n addItem(newItem);\n };\n\n const onCloudUploadSuccess = async (url: string, file: File) => {\n const newItem = await mediaManager.addItem({\n name: file.name,\n url,\n type: \"video\",\n metadata: { source: props.uploadConfig?.provider ?? \"s3\" },\n });\n addItem(newItem);\n };\n\n const visibleItems = items.slice(0, page * PAGE_SIZE);\n const canLoadMore = items.length > visibleItems.length;\n\n return (\n <>\n {props.uploadConfig && (\n <div className=\"flex panel-section\">\n <CloudMediaUpload\n uploadApiUrl={props.uploadConfig.uploadApiUrl}\n provider={props.uploadConfig.provider}\n accept=\"video/*\"\n onSuccess={onCloudUploadSuccess}\n buttonText=\"Upload video\"\n className=\"btn-ghost w-full\"\n />\n </div>\n )}\n <VideoPanel\n items={visibleItems}\n onItemSelect={handleSelection}\n onFileUpload={handleFileUpload}\n isLoading={isLoading}\n acceptFileTypes={acceptFileTypes}\n onUrlAdd={onUrlAdd}\n canLoadMore={canLoadMore}\n onLoadMore={() => setPage((prev) => prev + 1)}\n />\n </>\n );\n}\n\nfunction VideoPublicAssetsSection() {\n const assetLibrary = getAssetLibrary();\n const [providerConfigs, setProviderConfigs] = useState<AssetProviderConfig[]>(\n [],\n );\n const [activeProviderId, setActiveProviderId] = useState<string | \"all\">(\n \"all\",\n );\n const [publicItems, setPublicItems] = useState<MediaItem[]>([]);\n const [publicSearchQuery, setPublicSearchQuery] = useState(\"nature\");\n const [isPublicLoading, setIsPublicLoading] = useState(false);\n const [page, setPage] = useState(1);\n const [hasMore, setHasMore] = useState(true);\n const PAGE_SIZE = 10;\n\n useEffect(() => {\n const loadProviders = async () => {\n try {\n const configs = await assetLibrary.listPublicProviders();\n // Only show providers that actually support video\n setProviderConfigs(\n configs.filter((c) => c.supportedTypes?.includes(\"video\")),\n );\n } catch (err) {\n console.error(\"Failed to load asset providers\", err);\n }\n };\n void loadProviders();\n }, [assetLibrary]);\n\n const loadPublicAssets = async (query: string) => {\n setIsPublicLoading(true);\n try {\n const result = await assetLibrary.listAssets({\n source: \"public\",\n type: \"video\",\n query,\n page: 1,\n pageSize: PAGE_SIZE,\n provider: activeProviderId === \"all\" ? undefined : activeProviderId,\n });\n setPublicItems(result.items);\n setPage(1);\n setHasMore(result.items.length === PAGE_SIZE);\n } catch (err) {\n console.error(\"Failed to load public video assets\", err);\n setPublicItems([]);\n } finally {\n setIsPublicLoading(false);\n }\n };\n\n const throttledLoadPublicAssets = useMemo(\n () => throttle(loadPublicAssets, 1000),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [assetLibrary, activeProviderId],\n );\n\n useEffect(() => {\n void throttledLoadPublicAssets(publicSearchQuery);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeProviderId]);\n\n useEffect(() => {\n if (publicSearchQuery) {\n void throttledLoadPublicAssets(publicSearchQuery);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [publicSearchQuery]);\n\n const loadMore = async () => {\n if (!hasMore || isPublicLoading) return;\n const nextPage = page + 1;\n setIsPublicLoading(true);\n try {\n const result = await assetLibrary.listAssets({\n source: \"public\",\n type: \"video\",\n query: publicSearchQuery,\n page: nextPage,\n pageSize: PAGE_SIZE,\n provider: activeProviderId === \"all\" ? undefined : activeProviderId,\n });\n setPublicItems((prev) => [...prev, ...result.items]);\n setPage(nextPage);\n setHasMore(result.items.length === PAGE_SIZE);\n } catch (err) {\n console.error(\"Failed to load more public video assets\", err);\n } finally {\n setIsPublicLoading(false);\n }\n };\n\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"property-row\">\n <div className=\"property-row-label\">\n <span className=\"property-label\">Provider</span>\n </div>\n <div className=\"property-row-control\">\n <select\n className=\"select-dark\"\n value={activeProviderId}\n onChange={(e) =>\n setActiveProviderId(e.target.value as string | \"all\")\n }\n >\n <option value=\"all\">All providers</option>\n {providerConfigs\n .filter((p) => p.enabled)\n .map((p) => (\n <option key={p.id} value={p.id}>\n {p.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"property-row-control\">\n <SearchInput\n searchQuery={publicSearchQuery}\n setSearchQuery={(q) => {\n setPublicSearchQuery(q);\n }}\n />\n </div>\n </div>\n <VideoPanel\n items={publicItems}\n onItemSelect={() => {\n // Selection handled via timeline; public items behave same as user items\n }}\n onFileUpload={() => { }}\n isLoading={isPublicLoading}\n acceptFileTypes={[]}\n onUrlAdd={() => { }}\n showAddByUrl={false}\n canLoadMore={hasMore}\n onLoadMore={loadMore}\n />\n </>\n );\n}\n","/**\n * TextPanel Component\n * \n * A panel for creating and editing text elements in the studio. Provides comprehensive\n * text styling options including font selection, size, colors, stroke, and shadow effects.\n * \n * @component\n * @param {Object} props\n * @param {string} props.textContent - Text content to display\n * @param {number} props.fontSize - Font size in pixels\n * @param {string} props.selectedFont - Selected font family\n * @param {boolean} props.isBold - Whether text is bold\n * @param {boolean} props.isItalic - Whether text is italic\n * @param {string} props.textColor - Text color in hex format\n * @param {string} props.strokeColor - Stroke color in hex format\n * @param {boolean} props.applyShadow - Whether to apply shadow effect\n * @param {string} props.shadowColor - Shadow color in hex format\n * @param {number} props.strokeWidth - Width of text stroke\n * @param {boolean} props.applyBackground - Whether to apply background behind text\n * @param {string} props.backgroundColor - Background color in hex (when applyBackground is true)\n * @param {number} props.backgroundOpacity - Background opacity 0-1 (when applyBackground is true)\n * @param {string[]} props.fonts - Available font options\n * @param {(text: string) => void} props.setTextContent - Update text content\n * @param {(size: number) => void} props.setFontSize - Update font size\n * @param {(font: string) => void} props.setSelectedFont - Update selected font\n * @param {(bold: boolean) => void} props.setIsBold - Toggle bold style\n * @param {(italic: boolean) => void} props.setIsItalic - Toggle italic style\n * @param {(color: string) => void} props.setTextColor - Update text color\n * @param {(color: string) => void} props.setStrokeColor - Update stroke color\n * @param {(apply: boolean) => void} props.setApplyShadow - Toggle shadow effect\n * @param {(color: string) => void} props.setShadowColor - Update shadow color\n * @param {(width: number) => void} props.setStrokeWidth - Update stroke width\n * @param {(apply: boolean) => void} props.setApplyBackground - Toggle background\n * @param {(color: string) => void} props.setBackgroundColor - Update background color\n * @param {(opacity: number) => void} props.setBackgroundOpacity - Update background opacity\n * @param {() => void} props.handleApplyChanges - Apply text element changes\n * \n * @example\n * ```tsx\n * <TextPanel\n * textContent=\"Sample Text\"\n * fontSize={48}\n * selectedFont=\"Arial\"\n * isBold={false}\n * isItalic={false}\n * textColor=\"#000000\"\n * strokeColor=\"#ffffff\"\n * applyShadow={false}\n * shadowColor=\"#000000\"\n * strokeWidth={0}\n * fonts={[\"Arial\", \"Times New Roman\"]}\n * setTextContent={setText}\n * setFontSize={setSize}\n * // ... other handlers\n * />\n * ```\n */\n\nimport type { TextPanelState, TextPanelActions } from \"../../hooks/use-text-panel\";\n\nexport type TextPanelProps = TextPanelState & TextPanelActions;\n\nexport function TextPanel({\n textContent,\n fontSize,\n selectedFont,\n isBold,\n isItalic,\n textColor,\n strokeColor,\n applyShadow,\n shadowColor,\n strokeWidth,\n applyBackground,\n backgroundColor,\n backgroundOpacity,\n fonts,\n operation,\n setTextContent,\n setFontSize,\n setSelectedFont,\n setIsBold,\n setIsItalic,\n setTextColor,\n setStrokeColor,\n setApplyShadow,\n setShadowColor,\n setStrokeWidth,\n setApplyBackground,\n setBackgroundColor,\n setBackgroundOpacity,\n handleApplyChanges,\n}: TextPanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Text</div>\n {/* Text Content */}\n <div className=\"flex panel-section\">\n <input\n type=\"text\"\n value={textContent}\n placeholder=\"Sample\"\n onChange={(e) => setTextContent(e.target.value)}\n className=\"input-dark\"\n />\n </div>\n\n {/* Font Size */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Font Size</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"8\"\n max=\"120\"\n value={fontSize}\n onChange={(e) => setFontSize(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{fontSize}px</span>\n </div>\n </div>\n\n {/* Font */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Font</label>\n <div className=\"font-controls\">\n <select\n value={selectedFont}\n onChange={(e) => setSelectedFont(e.target.value)}\n className=\"select-dark\"\n >\n {fonts.map((font) => (\n <option key={font} value={font}>\n {font}\n </option>\n ))}\n </select>\n <button\n onClick={() => setIsBold(!isBold)}\n className={`btn-icon ${isBold ? 'btn-icon-active' : ''}`}\n >\n B\n </button>\n <button\n onClick={() => setIsItalic(!isItalic)}\n className={`btn-icon ${isItalic ? 'btn-icon-active' : ''}`}\n >\n I\n </button>\n </div>\n </div>\n\n {/* Colors */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Colors</label>\n <div className=\"color-section\">\n {/* Text Color */}\n <div className=\"color-control\">\n <label className=\"label-small\">Text Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={textColor}\n onChange={(e) => setTextColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={textColor}\n onChange={(e) => setTextColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n {/* Stroke Color */}\n <div className=\"color-control\">\n <label className=\"label-small\">Stroke Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n {/* Apply Shadow */}\n <div className=\"checkbox-control\">\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={applyShadow}\n onChange={(e) => setApplyShadow(e.target.checked)}\n className=\"checkbox-purple\"\n />\n Apply Shadow\n </label>\n </div>\n\n {/* Shadow Color - Only shown when shadow is enabled */}\n {applyShadow && (\n <div className=\"color-control\">\n <label className=\"label-small\">Shadow Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={shadowColor}\n onChange={(e) => setShadowColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={shadowColor}\n onChange={(e) => setShadowColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Stroke Width */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Stroke Width</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"2\"\n step={0.1}\n value={strokeWidth}\n onChange={(e) => setStrokeWidth(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{strokeWidth}</span>\n </div>\n </div>\n\n {/* Background (optional) */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Background</label>\n <div className=\"color-section\">\n <div className=\"checkbox-control\">\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={applyBackground}\n onChange={(e) => setApplyBackground(e.target.checked)}\n className=\"checkbox-purple\"\n />\n Apply Background\n </label>\n </div>\n {applyBackground && (\n <>\n <div className=\"color-control\">\n <label className=\"label-small\">Background Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={backgroundColor}\n onChange={(e) => setBackgroundColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={backgroundColor}\n onChange={(e) => setBackgroundColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n <div className=\"panel-section\">\n <label className=\"label-small\">Background Opacity</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step={0.1}\n value={backgroundOpacity}\n onChange={(e) => setBackgroundOpacity(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{Math.round(backgroundOpacity * 100)}%</span>\n </div>\n </div>\n </>\n )}\n </div>\n </div>\n\n {/* Operation button (only for creation, not edits) */}\n {operation !== \"Apply Changes\" && (\n <div className=\"flex panel-section\">\n <button onClick={handleApplyChanges} className=\"btn-primary w-full\">\n {operation}\n </button>\n </div>\n )}\n </div>\n );\n}","import { useEffect, useState } from \"react\";\nimport { TextElement, TrackElement, type TextAlign } from \"@twick/timeline\";\nimport { AVAILABLE_TEXT_FONTS } from \"@twick/video-editor\";\n\nexport const DEFAULT_TEXT_PROPS = {\n text: \"Sample\",\n fontSize: 48,\n fontFamily: \"Poppins\",\n fontWeight: 400,\n fontStyle: \"normal\",\n textColor: \"#ffffff\",\n strokeColor: \"#4d4d4d\",\n strokeWidth: 0,\n applyShadow: false,\n shadowColor: \"#000000\",\n textAlign: \"center\" as TextAlign,\n shadowOffset: [0, 0],\n shadowBlur: 2,\n shadowOpacity: 1.0,\n};\n\nexport interface TextPanelState {\n textContent: string;\n fontSize: number;\n selectedFont: string;\n isBold: boolean;\n isItalic: boolean;\n textColor: string;\n strokeColor: string;\n applyShadow: boolean;\n shadowColor: string;\n strokeWidth: number;\n applyBackground: boolean;\n backgroundColor: string;\n backgroundOpacity: number;\n fonts: string[];\n operation: string;\n}\n\nexport interface TextPanelActions {\n setTextContent: (text: string) => void;\n setFontSize: (size: number) => void;\n setSelectedFont: (font: string) => void;\n setIsBold: (bold: boolean) => void;\n setIsItalic: (italic: boolean) => void;\n setTextColor: (color: string) => void;\n setStrokeColor: (color: string) => void;\n setApplyShadow: (shadow: boolean) => void;\n setShadowColor: (color: string) => void;\n setStrokeWidth: (width: number) => void;\n setApplyBackground: (apply: boolean) => void;\n setBackgroundColor: (color: string) => void;\n setBackgroundOpacity: (opacity: number) => void;\n handleApplyChanges: () => void;\n}\n\nexport const useTextPanel = ({\n selectedElement,\n addElement,\n updateElement,\n}: {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}): TextPanelState & TextPanelActions => {\n const [textContent, setTextContent] = useState(DEFAULT_TEXT_PROPS.text);\n const [fontSize, setFontSize] = useState(DEFAULT_TEXT_PROPS.fontSize);\n const [selectedFont, setSelectedFont] = useState(DEFAULT_TEXT_PROPS.fontFamily);\n const [isBold, setIsBold] = useState(DEFAULT_TEXT_PROPS.fontWeight === 700);\n const [isItalic, setIsItalic] = useState(DEFAULT_TEXT_PROPS.fontStyle === \"italic\");\n const [textColor, setTextColor] = useState(DEFAULT_TEXT_PROPS.textColor);\n const [strokeColor, setStrokeColor] = useState(DEFAULT_TEXT_PROPS.strokeColor);\n const [applyShadow, setApplyShadow] = useState(DEFAULT_TEXT_PROPS.applyShadow);\n const [shadowColor, setShadowColor] = useState(DEFAULT_TEXT_PROPS.shadowColor);\n const [strokeWidth, setStrokeWidth] = useState(DEFAULT_TEXT_PROPS.strokeWidth);\n const [applyBackground, setApplyBackground] = useState(false);\n const [backgroundColor, setBackgroundColor] = useState(\"#FACC15\");\n const [backgroundOpacity, setBackgroundOpacity] = useState(1);\n\n const fonts = Object.values(AVAILABLE_TEXT_FONTS);\n\n const applyLiveChangesToExistingText = (overrides: Partial<TextPanelState> = {}) => {\n if (!(selectedElement instanceof TextElement)) {\n return;\n }\n\n const textElement = selectedElement;\n\n const nextState: Pick<\n TextPanelState,\n | \"textContent\"\n | \"fontSize\"\n | \"selectedFont\"\n | \"isBold\"\n | \"isItalic\"\n | \"textColor\"\n | \"strokeColor\"\n | \"strokeWidth\"\n | \"applyShadow\"\n | \"shadowColor\"\n | \"applyBackground\"\n | \"backgroundColor\"\n | \"backgroundOpacity\"\n > = {\n textContent,\n fontSize,\n selectedFont,\n isBold,\n isItalic,\n textColor,\n strokeColor,\n strokeWidth,\n applyShadow,\n shadowColor,\n applyBackground,\n backgroundColor,\n backgroundOpacity,\n ...overrides,\n };\n\n textElement.setText(nextState.textContent);\n textElement.setFontSize(nextState.fontSize);\n textElement.setFontFamily(nextState.selectedFont);\n textElement.setFontWeight(nextState.isBold ? 700 : 400);\n textElement.setFontStyle(nextState.isItalic ? \"italic\" : \"normal\");\n textElement.setFill(nextState.textColor);\n textElement.setStrokeColor(nextState.strokeColor);\n textElement.setLineWidth(nextState.strokeWidth);\n textElement.setTextAlign(DEFAULT_TEXT_PROPS.textAlign);\n\n const nextProps = { ...textElement.getProps() };\n\n if (nextState.applyShadow) {\n nextProps.shadowColor = nextState.shadowColor;\n nextProps.shadowOffset = DEFAULT_TEXT_PROPS.shadowOffset;\n nextProps.shadowBlur = DEFAULT_TEXT_PROPS.shadowBlur;\n nextProps.shadowOpacity = DEFAULT_TEXT_PROPS.shadowOpacity;\n } else {\n nextProps.shadowColor = undefined;\n nextProps.shadowOffset = undefined;\n nextProps.shadowBlur = undefined;\n nextProps.shadowOpacity = undefined;\n }\n\n if (nextState.applyBackground) {\n nextProps.backgroundColor = nextState.backgroundColor;\n nextProps.backgroundOpacity = nextState.backgroundOpacity;\n } else {\n nextProps.backgroundColor = undefined;\n nextProps.backgroundOpacity = undefined;\n }\n\n textElement.setProps(nextProps);\n updateElement(textElement);\n };\n\n const handleTextContentChange = (text: string) => {\n setTextContent(text);\n applyLiveChangesToExistingText({ textContent: text });\n };\n\n const handleFontSizeChange = (size: number) => {\n setFontSize(size);\n applyLiveChangesToExistingText({ fontSize: size });\n };\n\n const handleSelectedFontChange = (font: string) => {\n setSelectedFont(font);\n applyLiveChangesToExistingText({ selectedFont: font });\n };\n\n const handleIsBoldChange = (bold: boolean) => {\n setIsBold(bold);\n applyLiveChangesToExistingText({ isBold: bold });\n };\n\n const handleIsItalicChange = (italic: boolean) => {\n setIsItalic(italic);\n applyLiveChangesToExistingText({ isItalic: italic });\n };\n\n const handleTextColorChange = (color: string) => {\n setTextColor(color);\n applyLiveChangesToExistingText({ textColor: color });\n };\n\n const handleStrokeColorChange = (color: string) => {\n setStrokeColor(color);\n applyLiveChangesToExistingText({ strokeColor: color });\n };\n\n const handleStrokeWidthChange = (width: number) => {\n setStrokeWidth(width);\n applyLiveChangesToExistingText({ strokeWidth: width });\n };\n\n const handleApplyShadowChange = (shadow: boolean) => {\n setApplyShadow(shadow);\n applyLiveChangesToExistingText({ applyShadow: shadow });\n };\n\n const handleShadowColorChange = (color: string) => {\n setShadowColor(color);\n applyLiveChangesToExistingText({ shadowColor: color });\n };\n\n const handleApplyBackgroundChange = (apply: boolean) => {\n setApplyBackground(apply);\n applyLiveChangesToExistingText({ applyBackground: apply });\n };\n\n const handleBackgroundColorChange = (color: string) => {\n setBackgroundColor(color);\n applyLiveChangesToExistingText({ backgroundColor: color });\n };\n\n const handleBackgroundOpacityChange = (opacity: number) => {\n setBackgroundOpacity(opacity);\n applyLiveChangesToExistingText({ backgroundOpacity: opacity });\n };\n\n const handleApplyChanges = async () => {\n // For existing text elements, changes are already applied live via the handlers above.\n // The apply button is only meaningful when creating a new text element.\n if (selectedElement instanceof TextElement) {\n return;\n }\n\n const textElement = new TextElement(textContent)\n .setFontSize(fontSize)\n .setFontFamily(selectedFont)\n .setFontWeight(isBold ? 700 : 400)\n .setFontStyle(isItalic ? \"italic\" : \"normal\")\n .setFill(textColor)\n .setStrokeColor(strokeColor)\n .setLineWidth(strokeWidth)\n .setTextAlign(\"center\");\n\n const nextProps = { ...textElement.getProps() };\n if (applyShadow) {\n nextProps.shadowColor = shadowColor;\n nextProps.shadowOffset = DEFAULT_TEXT_PROPS.shadowOffset;\n nextProps.shadowBlur = DEFAULT_TEXT_PROPS.shadowBlur;\n nextProps.shadowOpacity = DEFAULT_TEXT_PROPS.shadowOpacity;\n }\n if (applyBackground) {\n nextProps.backgroundColor = backgroundColor;\n nextProps.backgroundOpacity = backgroundOpacity;\n }\n textElement.setProps(nextProps);\n await addElement(textElement);\n };\n\n useEffect(() => {\n if (selectedElement instanceof TextElement) {\n setTextContent(selectedElement.getText());\n const textProps = selectedElement.getProps();\n setSelectedFont(textProps.fontFamily ?? DEFAULT_TEXT_PROPS.fontFamily);\n setFontSize(textProps.fontSize ?? DEFAULT_TEXT_PROPS.fontSize);\n setIsBold(textProps.fontWeight === 700);\n setIsItalic(textProps.fontStyle === \"italic\");\n setTextColor(textProps.fill ?? DEFAULT_TEXT_PROPS.textColor);\n setStrokeColor(textProps.stroke ?? DEFAULT_TEXT_PROPS.strokeColor);\n setStrokeWidth(textProps.lineWidth ?? DEFAULT_TEXT_PROPS.strokeWidth);\n const hasShadow = textProps.shadowColor !== undefined;\n setApplyShadow(hasShadow);\n if (hasShadow) {\n setShadowColor(textProps.shadowColor ?? DEFAULT_TEXT_PROPS.shadowColor);\n }\n const hasBackground = textProps.backgroundColor != null && textProps.backgroundColor !== \"\";\n setApplyBackground(hasBackground);\n if (hasBackground) {\n setBackgroundColor(textProps.backgroundColor ?? \"#FACC15\");\n setBackgroundOpacity(textProps.backgroundOpacity ?? 1);\n }\n } else {\n setTextContent(DEFAULT_TEXT_PROPS.text);\n setFontSize(DEFAULT_TEXT_PROPS.fontSize);\n setSelectedFont(DEFAULT_TEXT_PROPS.fontFamily);\n setIsBold(DEFAULT_TEXT_PROPS.fontWeight === 700);\n setIsItalic(DEFAULT_TEXT_PROPS.fontStyle === \"italic\");\n setTextColor(DEFAULT_TEXT_PROPS.textColor);\n setStrokeColor(DEFAULT_TEXT_PROPS.strokeColor);\n setStrokeWidth(DEFAULT_TEXT_PROPS.strokeWidth);\n setApplyShadow(DEFAULT_TEXT_PROPS.applyShadow);\n setShadowColor(DEFAULT_TEXT_PROPS.shadowColor);\n setApplyBackground(false);\n setBackgroundColor(\"#FACC15\");\n setBackgroundOpacity(1);\n }\n }, [selectedElement]);\n\n return {\n textContent,\n fontSize,\n selectedFont,\n isBold,\n isItalic,\n textColor,\n strokeColor,\n applyShadow,\n shadowColor,\n strokeWidth,\n fonts,\n operation: selectedElement instanceof TextElement ? \"Apply Changes\": \"Add Text\",\n setTextContent: handleTextContentChange,\n setFontSize: handleFontSizeChange,\n setSelectedFont: handleSelectedFontChange,\n setIsBold: handleIsBoldChange,\n setIsItalic: handleIsItalicChange,\n setTextColor: handleTextColorChange,\n setStrokeColor: handleStrokeColorChange,\n setApplyShadow: handleApplyShadowChange,\n setShadowColor: handleShadowColorChange,\n setStrokeWidth: handleStrokeWidthChange,\n applyBackground,\n backgroundColor,\n backgroundOpacity,\n setApplyBackground: handleApplyBackgroundChange,\n setBackgroundColor: handleBackgroundColorChange,\n setBackgroundOpacity: handleBackgroundOpacityChange,\n handleApplyChanges,\n };\n};\n","import { TrackElement } from \"@twick/timeline\";\nimport { TextPanel } from \"../panel/text-panel\";\nimport { useTextPanel } from \"../../hooks/use-text-panel\";\n\ninterface TextPanelContainerProps {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}\n\nexport function TextPanelContainer(props: TextPanelContainerProps) {\n const textPanelProps = useTextPanel(props);\n return <TextPanel {...textPanelProps} />;\n}\n","import { TextElement } from \"@twick/timeline\";\nimport { AVAILABLE_TEXT_FONTS } from \"@twick/video-editor\";\n\ninterface TextStylePanelProps {\n addElement: (element: TextElement) => void;\n}\n\ninterface TextStylePreset {\n id: string;\n label: string;\n description: string;\n fontFamily: string;\n fontSize: number;\n fontWeight: number;\n textColor: string;\n strokeColor: string;\n strokeWidth: number;\n applyShadow: boolean;\n shadowColor?: string;\n applyBackground: boolean;\n backgroundColor?: string;\n backgroundOpacity?: number;\n}\n\nconst TEXT_STYLE_PRESETS: TextStylePreset[] = [\n // Utility / captions\n {\n id: \"classic-subtitle\",\n label: \"Classic Subtitle\",\n description: \"White text with subtle outline\",\n fontFamily: AVAILABLE_TEXT_FONTS.ROBOTO,\n fontSize: 32,\n fontWeight: 500,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 0.5,\n applyShadow: false,\n applyBackground: false,\n },\n {\n id: \"minimal-subtitle\",\n label: \"Minimal Subtitle\",\n description: \"Clean white text, no effects\",\n fontFamily: AVAILABLE_TEXT_FONTS.MULISH,\n fontSize: 30,\n fontWeight: 500,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: false,\n },\n {\n id: \"impact-caption\",\n label: \"Impact Caption\",\n description: \"Bold white with strong outline\",\n fontFamily: AVAILABLE_TEXT_FONTS.IMPACT,\n fontSize: 34,\n fontWeight: 700,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 1,\n applyShadow: false,\n applyBackground: false,\n },\n {\n id: \"bar-caption\",\n label: \"Bar Caption\",\n description: \"White text on dark bar\",\n fontFamily: AVAILABLE_TEXT_FONTS.RUBIK,\n fontSize: 30,\n fontWeight: 600,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: true,\n backgroundColor: \"#020617\",\n backgroundOpacity: 0.85,\n },\n // Titles\n {\n id: \"big-title\",\n label: \"Big Title\",\n description: \"Large bold center title\",\n fontFamily: AVAILABLE_TEXT_FONTS.LUCKIEST_GUY,\n fontSize: 56,\n fontWeight: 700,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 0.5,\n applyShadow: true,\n shadowColor: \"#000000\",\n applyBackground: false,\n },\n {\n id: \"minimal-title\",\n label: \"Minimal Title\",\n description: \"Lightweight clean heading\",\n fontFamily: AVAILABLE_TEXT_FONTS.PLAYFAIR_DISPLAY,\n fontSize: 42,\n fontWeight: 400,\n textColor: \"#E5E7EB\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: false,\n },\n {\n id: \"highlight-title\",\n label: \"Highlight Title\",\n description: \"Bold on yellow highlight\",\n fontFamily: AVAILABLE_TEXT_FONTS.POPPINS,\n fontSize: 40,\n fontWeight: 700,\n textColor: \"#111827\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: true,\n backgroundColor: \"#FACC15\",\n backgroundOpacity: 0.9,\n },\n {\n id: \"outline-title\",\n label: \"Outline Title\",\n description: \"Bold outlined title\",\n fontFamily: AVAILABLE_TEXT_FONTS.KUMAR_ONE_OUTLINE,\n fontSize: 48,\n fontWeight: 700,\n textColor: \"#000000\",\n strokeColor: \"#FFFFFF\",\n strokeWidth: 1.2,\n applyShadow: false,\n applyBackground: false,\n },\n // Social / handle\n {\n id: \"handle-chip\",\n label: \"Handle Chip\",\n description: \"@handle chip style\",\n fontFamily: AVAILABLE_TEXT_FONTS.RUBIK,\n fontSize: 26,\n fontWeight: 600,\n textColor: \"#0F172A\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: true,\n backgroundColor: \"#E5E7EB\",\n backgroundOpacity: 1,\n },\n {\n id: \"cta-pill\",\n label: \"CTA Pill\",\n description: \"Call-to-action pill\",\n fontFamily: AVAILABLE_TEXT_FONTS.IMPACT,\n fontSize: 28,\n fontWeight: 700,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: true,\n backgroundColor: \"#22C55E\",\n backgroundOpacity: 1,\n },\n];\n\nexport function TextStylePanel({ addElement }: TextStylePanelProps) {\n const createTextFromPreset = async (preset: TextStylePreset) => {\n const textElement = new TextElement(\"Sample\")\n .setFontSize(preset.fontSize)\n .setFontFamily(preset.fontFamily)\n .setFontWeight(preset.fontWeight)\n .setFontStyle(\"normal\")\n .setFill(preset.textColor)\n .setStrokeColor(preset.strokeColor)\n .setLineWidth(preset.strokeWidth)\n .setTextAlign(\"center\");\n\n const nextProps = { ...textElement.getProps() };\n\n if (preset.applyShadow && preset.shadowColor) {\n nextProps.shadowColor = preset.shadowColor;\n nextProps.shadowOffset = [0, 0];\n nextProps.shadowBlur = 2;\n nextProps.shadowOpacity = 1;\n }\n\n if (preset.applyBackground && preset.backgroundColor) {\n nextProps.backgroundColor = preset.backgroundColor;\n nextProps.backgroundOpacity = preset.backgroundOpacity ?? 1;\n }\n\n textElement.setProps(nextProps);\n\n await addElement(textElement);\n };\n\n const handlePresetClick = (preset: TextStylePreset) => {\n void createTextFromPreset(preset);\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Text Style</div>\n <div className=\"panel-section\">\n <div className=\"text-style-grid\">\n {TEXT_STYLE_PRESETS.map((preset) => (\n <button\n key={preset.id}\n type=\"button\"\n className=\"text-style-card\"\n onClick={() => handlePresetClick(preset)}\n >\n <div className=\"text-style-preview\">\n <div\n style={{\n padding: preset.applyBackground ? \"0.35rem 0.9rem\" : 0,\n borderRadius: preset.applyBackground ? \"999px\" : 0,\n backgroundColor: preset.applyBackground\n ? preset.backgroundColor\n : \"transparent\",\n boxShadow:\n preset.applyBackground && preset.backgroundOpacity && preset.backgroundOpacity > 0.8\n ? \"0 0 20px rgba(0, 0, 0, 0.55)\"\n : undefined,\n }}\n >\n <span\n style={{\n fontFamily: preset.fontFamily,\n fontWeight: preset.fontWeight,\n // Scale preview size relative to configured size but clamp for tiles\n fontSize: Math.max(10, Math.min(18, preset.fontSize * 0.35)),\n color: preset.textColor,\n WebkitTextStroke:\n preset.strokeWidth > 0\n ? `${preset.strokeWidth}px ${preset.strokeColor}`\n : undefined,\n textShadow:\n preset.applyShadow && preset.shadowColor\n ? `0 0 16px ${preset.shadowColor}`\n : undefined,\n }}\n >\n {preset.label}\n </span>\n </div>\n </div>\n </button>\n ))}\n </div>\n </div>\n </div>\n );\n}\n\n","import type { TrackElement } from \"@twick/timeline\";\nimport { TextStylePanel } from \"../panel/text-style-panel\";\n\ninterface TextStylePanelContainerProps {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}\n\nexport function TextStylePanelContainer({ addElement }: TextStylePanelContainerProps) {\n return (\n <TextStylePanel\n addElement={addElement}\n />\n );\n}\n\n","export const BASIC_VERTEX_SHADER = `\n attribute vec2 a_position;\n attribute vec2 a_texCoord;\n varying vec2 v_texCoord;\n void main() {\n v_texCoord = a_texCoord;\n gl_Position = vec4(a_position, 0.0, 1.0);\n }\n`;\nconst SEPIA_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uIntensity;\n void main() {\n vec4 color = texture2D(uTexture, v_texCoord);\n vec3 c = color.rgb;\n vec3 sepia = vec3(\n dot(c, vec3(0.393, 0.769, 0.189)),\n dot(c, vec3(0.349, 0.686, 0.168)),\n dot(c, vec3(0.272, 0.534, 0.131))\n );\n vec3 mixed = mix(c, sepia, clamp(uIntensity, 0.0, 1.0));\n gl_FragColor = vec4(mixed, color.a);\n }\n`;\nconst VIGNETTE_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uIntensity;\n void main() {\n vec2 uv = v_texCoord - 0.5;\n float dist = length(uv);\n float vignette = smoothstep(0.8, 0.3, dist);\n vec4 color = texture2D(uTexture, v_texCoord);\n color.rgb *= mix(1.0, vignette, clamp(uIntensity, 0.0, 1.0));\n gl_FragColor = color;\n }\n`;\nconst PIXELATE_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform vec2 uResolution;\n uniform float uIntensity;\n void main() {\n float pixelSize = mix(1.0, 20.0, clamp(uIntensity, 0.0, 1.0));\n vec2 uv = v_texCoord;\n vec2 coord = floor(uv * uResolution / pixelSize) * pixelSize / uResolution;\n vec4 color = texture2D(uTexture, coord);\n gl_FragColor = color;\n }\n`;\nconst WARP_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n void main() {\n vec2 uv = v_texCoord;\n float strength = 0.03 * uIntensity;\n uv.x += sin(uv.y * 20.0 + uTime * 10.0) * strength;\n uv.y += cos(uv.x * 20.0 + uTime * 8.0) * strength;\n vec4 color = texture2D(uTexture, uv);\n gl_FragColor = color;\n }\n`;\n// Simplified from openvideo \"Glitch\" style effect: time-based slice + RGB offset.\nconst GLITCH_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(float n) { return fract(sin(n) * 43758.5453123); }\n float rand2(vec2 p) { return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); }\n\n void main(void) {\n vec2 uv = v_texCoord;\n\n // Slice count and RGB offset scale with intensity\n float sliceCount = mix(6.0, 24.0, clamp(uIntensity, 0.0, 1.0));\n float baseShift = 0.01 * clamp(uIntensity, 0.0, 1.0);\n\n float sliceId = floor(uv.y * sliceCount);\n float sliceShift = (rand(sliceId + uTime * 10.0) - 0.5) * 0.25 * baseShift;\n uv.x += sliceShift;\n\n float rShift = baseShift;\n float gShift = -baseShift * 0.5;\n float bShift = baseShift * 0.75;\n\n vec3 col;\n col.r = texture2D(uTexture, uv + vec2(rShift, 0.0)).r;\n col.g = texture2D(uTexture, uv + vec2(gShift, 0.0)).g;\n col.b = texture2D(uTexture, uv + vec2(bShift, 0.0)).b;\n\n float noise = rand2(vec2(uTime * 50.0, uv.y * 100.0));\n float noiseIntensity = noise * 0.2 * clamp(uIntensity, 0.0, 1.0);\n\n col += noiseIntensity;\n gl_FragColor = vec4(col, 1.0);\n }\n`;\n// RGB shift / chromatic aberration style effect.\nconst RGB_SHIFT_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n if (base.a < 0.01) {\n gl_FragColor = base;\n return;\n }\n\n float shiftAmount = mix(0.001, 0.02, clamp(uIntensity, 0.0, 1.0));\n float angle = 0.5 + sin(uTime * 0.7) * 0.5;\n vec2 dir = vec2(cos(angle), sin(angle));\n\n float wobble = sin(uTime * 10.0) * shiftAmount * 0.5;\n\n vec2 rUV = clamp(uv + dir * shiftAmount + vec2(wobble, 0.0), 0.0, 1.0);\n vec2 gUV = clamp(uv, 0.0, 1.0);\n vec2 bUV = clamp(uv - dir * shiftAmount - vec2(wobble, 0.0), 0.0, 1.0);\n\n float r = texture2D(uTexture, rUV).r;\n float g = texture2D(uTexture, gUV).g;\n float b = texture2D(uTexture, bUV).b;\n\n gl_FragColor = vec4(r, g, b, base.a);\n }\n`;\n// Halftone / dot pattern – intensity controls dot size and strength.\nconst HALFTONE_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float luminance(vec3 c) {\n return dot(c, vec3(0.299, 0.587, 0.114));\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n\n float angle = uTime * 0.3;\n float ca = cos(angle);\n float sa = sin(angle);\n mat2 rot = mat2(ca, -sa, sa, ca);\n vec2 rotatedUV = rot * (uv - 0.5) + 0.5;\n\n float dotSize = mix(0.06, 0.015, clamp(uIntensity, 0.0, 1.0));\n vec2 grid = rotatedUV / dotSize;\n vec2 cell = floor(grid) + 0.5;\n vec2 cellCenter = cell * dotSize;\n\n vec4 texColor = texture2D(uTexture, uv);\n float lum = luminance(texColor.rgb);\n float radius = (1.0 - lum) * dotSize * 0.5;\n\n float dist = distance(rotatedUV, cellCenter);\n float mask = smoothstep(radius, radius * 0.8, dist);\n\n vec3 halftone = texColor.rgb * mask;\n float mixAmount = clamp(uIntensity, 0.0, 1.0);\n texColor.rgb = mix(texColor.rgb, halftone, mixAmount);\n\n gl_FragColor = texColor;\n }\n`;\n// Animated hue shift; intensity controls mix amount.\nconst HUE_SHIFT_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n vec3 hueShift(vec3 color, float angle) {\n float cosA = cos(angle);\n float sinA = sin(angle);\n mat3 rot = mat3(\n 0.299 + 0.701 * cosA + 0.168 * sinA,\n 0.587 - 0.587 * cosA + 0.330 * sinA,\n 0.114 - 0.114 * cosA - 0.497 * sinA,\n\n 0.299 - 0.299 * cosA - 0.328 * sinA,\n 0.587 + 0.413 * cosA + 0.035 * sinA,\n 0.114 - 0.114 * cosA + 0.292 * sinA,\n\n 0.299 - 0.300 * cosA + 1.250 * sinA,\n 0.587 - 0.588 * cosA - 1.050 * sinA,\n 0.114 + 0.886 * cosA - 0.203 * sinA\n );\n return color * rot;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 tex = texture2D(uTexture, uv);\n float amount = clamp(uIntensity, 0.0, 1.0);\n\n vec3 shifted = hueShift(tex.rgb, uTime * 2.5);\n tex.rgb = mix(tex.rgb, shifted, amount);\n\n gl_FragColor = tex;\n }\n`;\n// Horizontal wave distortion – intensity controls strength.\nconst WAVE_DISTORT_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n void main(void) {\n vec2 uv = v_texCoord;\n float strength = mix(0.0, 0.03, clamp(uIntensity, 0.0, 1.0));\n float time = uTime * 10.0;\n float wave = sin((uv.y * 18.0) - time);\n float offsetX = wave * strength;\n vec2 distortedUV = clamp(uv + vec2(offsetX, 0.0), 0.0, 1.0);\n vec4 color = texture2D(uTexture, distortedUV);\n gl_FragColor = color;\n }\n`;\n// TV scanlines and subtle noise.\nconst TV_SCANLINES_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(vec2 p) {\n return fract(sin(dot(p ,vec2(12.9898,78.233))) * 43758.5453);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 tex = texture2D(uTexture, uv);\n vec3 base = tex.rgb;\n\n float lineThickness = mix(1.0, 3.0, clamp(uIntensity, 0.0, 1.0));\n float line = sin(uv.y * 800.0 * lineThickness) * 0.5 + 0.5;\n float lineIntensity = mix(0.2, 0.8, clamp(uIntensity, 0.0, 1.0));\n line = mix(1.0, line, lineIntensity);\n\n float noise = (rand(vec2(uTime, uv.y * 1000.0)) - 0.5) * 0.1 * clamp(uIntensity, 0.0, 1.0);\n vec3 color = base * line + noise;\n\n gl_FragColor = vec4(color, tex.a);\n }\n`;\n// Simple HDR-ish tone mapping based on exposure/contrast driven by intensity.\nconst HDR_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uIntensity;\n\n vec3 adjustContrast(vec3 color, float contrast) {\n return (color - 0.5) * contrast + 0.5;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 tex = texture2D(uTexture, uv);\n vec3 color = tex.rgb;\n\n float exposure = mix(1.0, 1.8, clamp(uIntensity, 0.0, 1.0));\n float contrast = mix(1.0, 2.0, clamp(uIntensity, 0.0, 1.0));\n\n color *= exposure;\n color = adjustContrast(color, contrast);\n color = color / (color + vec3(1.0));\n\n gl_FragColor = vec4(color, tex.a);\n }\n`;\n// Retro 70s: sepia-ish fade + grain + vignette.\nconst RETRO_70S_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float noise(vec2 p) {\n return fract(sin(dot(p, vec2(12.9898,78.233)) + uTime) * 43758.5453);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 tex = texture2D(uTexture, uv);\n vec3 color = tex.rgb;\n\n // Sepia-like fade\n vec3 sepia = vec3(\n dot(color, vec3(0.393, 0.769, 0.189)),\n dot(color, vec3(0.349, 0.686, 0.168)),\n dot(color, vec3(0.272, 0.534, 0.131))\n );\n float fade = clamp(uIntensity, 0.0, 1.0);\n vec3 faded = mix(color, sepia, mix(0.4, 0.9, fade));\n\n // Film grain\n float grainAmount = mix(0.0, 0.12, fade);\n float grain = (noise(uv * 500.0) - 0.5) * grainAmount;\n faded += grain;\n\n // Slight flicker\n float flicker = 0.97 + 0.03 * sin(uTime * 60.0);\n faded *= flicker;\n\n // Vignette\n float dist = distance(uv, vec2(0.5));\n float vignette = smoothstep(0.8, 1.0, dist);\n float vignetteStrength = mix(0.0, 1.0, fade);\n faded *= (1.0 - vignette * vignetteStrength);\n\n gl_FragColor = vec4(faded, tex.a);\n }\n`;\n// Bubble-style sparkles around the frame.\nconst BUBBLE_SPARKLES_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(vec2 co) {\n return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);\n }\n\n float softCircle(vec2 uv, vec2 c, float r) {\n float d = distance(uv, c);\n return 1.0 - smoothstep(r * 0.6, r, d);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 fg = texture2D(uTexture, uv);\n\n float bubbles = 0.0;\n float count = mix(20.0, 120.0, clamp(uIntensity, 0.0, 1.0));\n\n for (float i = 0.0; i < 200.0; i++) {\n if (i >= count) break;\n float t = uTime * 0.7 + i * 0.13;\n vec2 pos = vec2(rand(vec2(i, 1.23)), rand(vec2(i, 4.56)));\n float radius = mix(0.01, 0.03, rand(vec2(i, 9.87)));\n pos.y = fract(pos.y + t * 0.1);\n bubbles += softCircle(uv, pos, radius);\n }\n\n vec3 bubbleColor = vec3(1.0, 0.9, 0.5);\n fg.rgb += bubbleColor * bubbles * clamp(uIntensity, 0.0, 1.0);\n gl_FragColor = fg;\n }\n`;\n// Heart-shaped sparkles.\nconst HEART_SPARKLES_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(vec2 co) {\n return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);\n }\n\n float heartShape(vec2 p) {\n p = (p - 0.5) * 2.0;\n p.y = -p.y;\n p.y += 0.25;\n float x = p.x;\n float y = p.y;\n float v = pow(x*x + y*y - 1.0, 3.0) - x*x*y*y*y;\n return smoothstep(0.0, 0.02, -v);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n float hearts = 0.0;\n float count = mix(10.0, 80.0, clamp(uIntensity, 0.0, 1.0));\n\n for (float i = 0.0; i < 120.0; i++) {\n if (i >= count) break;\n vec2 pos = vec2(rand(vec2(i, 1.234)), rand(vec2(i, 5.678)));\n float size = mix(0.02, 0.05, rand(vec2(i, 9.1011)));\n float vibX = (rand(vec2(i, uTime)) - 0.5) * 0.02;\n float vibY = (rand(vec2(i + 1.0, uTime)) - 0.5) * 0.02;\n vec2 hUV = (uv - (pos + vec2(vibX, vibY))) / size + 0.5;\n float h = heartShape(hUV);\n float pulse = sin(uTime * 4.0 + i) * 0.2 + 1.0;\n hearts += h * pulse;\n }\n\n vec3 heartColor = vec3(1.0, 0.3, 0.6);\n base.rgb += heartColor * hearts * clamp(uIntensity, 0.0, 1.0);\n gl_FragColor = base;\n }\n`;\n// Butterfly-shaped sparkles.\nconst BUTTERFLY_SPARKLES_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(vec2 co) {\n return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);\n }\n\n float wing(vec2 p) {\n float d = pow(p.x, 2.0) + pow(p.y * 1.2, 2.0);\n return smoothstep(0.3, 0.0, d);\n }\n\n float butterflyShape(vec2 uv) {\n vec2 p = (uv - 0.5) * 2.0;\n float body = smoothstep(0.12, 0.05, abs(p.x)) * smoothstep(0.4, 0.0, abs(p.y));\n float wL = wing(vec2(p.x * 1.2 + 0.6, p.y));\n float wR = wing(vec2(p.x * 1.2 - 0.6, p.y));\n return clamp(wL + wR + body, 0.0, 1.0);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n float butterflies = 0.0;\n float count = mix(8.0, 40.0, clamp(uIntensity, 0.0, 1.0));\n\n for (float i = 0.0; i < 80.0; i++) {\n if (i >= count) break;\n vec2 pos = vec2(rand(vec2(i, 1.234)), rand(vec2(i, 5.678)));\n float size = mix(0.03, 0.08, rand(vec2(i, 9.1011)));\n float vibX = (rand(vec2(i, uTime)) - 0.5) * 0.02;\n float vibY = (rand(vec2(i + 1.0, uTime)) - 0.5) * 0.02;\n vec2 bUV = (uv - (pos + vec2(vibX, vibY))) / size + 0.5;\n float b = butterflyShape(bUV);\n float pulse = sin(uTime * 3.0 + i) * 0.25 + 1.0;\n butterflies += b * pulse;\n }\n\n vec3 butterflyColor = vec3(0.5, 0.6, 1.0);\n base.rgb += butterflyColor * butterflies * clamp(uIntensity, 0.0, 1.0);\n gl_FragColor = base;\n }\n`;\n// Radial lightning bolt + explosion.\nconst LIGHTNING_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec2 center = vec2(0.5, 0.5);\n float dist = distance(uv, center);\n\n float speed = 0.7;\n float progress = mod(uTime * speed, 1.0);\n float width = mix(0.01, 0.07, progress);\n float lightning = smoothstep(progress + width, progress, dist);\n float noise = sin((uv.x + uv.y) * 40.0 + uTime * 12.0) * 0.5 + 0.5;\n lightning *= noise;\n\n float explosion = smoothstep(0.85, 1.0, progress);\n float burst = explosion * smoothstep(0.25, 0.0, dist);\n\n vec3 lightningColor = vec3(1.0, 0.9, 0.6) * lightning * 2.0;\n vec3 explosionColor = vec3(1.0, 0.4, 0.2) * burst * 3.0;\n\n vec4 base = texture2D(uTexture, uv);\n vec3 mixed = base.rgb + (lightningColor + explosionColor) * clamp(uIntensity, 0.0, 1.0);\n gl_FragColor = vec4(mixed, base.a);\n }\n`;\n// Lightning veins / energy center.\nconst LIGHTNING_VEINS_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n }\n\n float noise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n float a = hash(i);\n float b = hash(i + vec2(1.0, 0.0));\n float c = hash(i + vec2(0.0, 1.0));\n float d = hash(i + vec2(1.0, 1.0));\n vec2 u = f * f * (3.0 - 2.0 * f);\n return mix(a, b, u.x) +\n (c - a) * u.y * (1.0 - u.x) +\n (d - b) * u.x * u.y;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec2 center = vec2(0.5);\n vec2 dir = uv - center;\n float dist = length(dir);\n float t = uTime * 1.5;\n\n float veinNoise = noise(dir * 6.0 + t) * 0.6 +\n noise(dir * 12.0 - t * 1.3) * 0.3;\n float warpedDist = dist + veinNoise * 0.08;\n float thickness = 0.04 + veinNoise * 0.02;\n float lightning = smoothstep(thickness, 0.0, warpedDist);\n\n float branches = smoothstep(0.02, 0.0, abs(noise(dir * 20.0 + t) - 0.5));\n lightning += branches * 0.35;\n\n float pulse = sin(uTime * 10.0) * 0.3 + 0.7;\n lightning *= pulse;\n\n vec3 veinColor = vec3(0.6, 0.85, 1.0) * lightning * 2.5 * clamp(uIntensity, 0.0, 1.0);\n vec4 base = texture2D(uTexture, uv);\n gl_FragColor = vec4(base.rgb + veinColor, base.a);\n }\n`;\n// Sparks particles.\nconst SPARKS_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n }\n\n vec3 randomColor(float h) {\n return vec3(\n 0.5 + 0.5 * sin(h * 6.2831),\n 0.5 + 0.5 * sin(h * 6.2831 + 2.1),\n 0.5 + 0.5 * sin(h * 6.2831 + 4.2)\n );\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n vec3 sparkColor = vec3(0.0);\n float sparkAlpha = 0.0;\n\n float density = mix(10.0, 40.0, clamp(uIntensity, 0.0, 1.0));\n vec2 grid = floor(uv * density);\n float h = hash(grid);\n vec2 offset = vec2(fract(h * 13.3), fract(h * 7.7 + uTime * 2.0));\n vec2 cellUV = fract(uv * density) - offset;\n float d = length(cellUV);\n\n float size = mix(0.1, 0.25, clamp(uIntensity, 0.0, 1.0));\n float spark = smoothstep(size, 0.0, d);\n vec3 color = randomColor(h) * spark;\n sparkColor += color;\n sparkAlpha += spark;\n\n vec3 finalColor = base.rgb + sparkColor;\n gl_FragColor = vec4(finalColor, max(base.a, sparkAlpha));\n }\n`;\n// Horizontal laser beam across the frame.\nconst LASER_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float noise(float x) {\n return sin(x * 40.0) * 0.005;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 baseColor = texture2D(uTexture, uv);\n\n float beamY = 0.5 + noise(uv.x + uTime * 5.0);\n float thickness = mix(0.01, 0.04, clamp(uIntensity, 0.0, 1.0));\n float dist = abs(uv.y - beamY);\n\n float core = smoothstep(thickness, 0.0, dist);\n float glow = smoothstep(thickness * 4.0, thickness, dist);\n float pulse = 0.6 + 0.4 * sin(uTime * 10.0);\n float laserMask = (core + glow * 1.5) * pulse * clamp(uIntensity, 0.0, 1.0);\n\n vec3 laserColor = vec3(1.0, 0.1, 0.3) * laserMask;\n vec3 color = baseColor.rgb + laserColor;\n gl_FragColor = vec4(color, baseColor.a);\n }\n`;\n// Water reflection in lower half of frame.\nconst WATER_REFLECTION_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n void main(void) {\n vec2 uv = v_texCoord;\n\n if (uv.y < 0.5) {\n gl_FragColor = texture2D(uTexture, uv);\n return;\n }\n\n vec2 reflectUV = uv;\n reflectUV.y = 1.0 - uv.y;\n float wave =\n sin(reflectUV.y * 30.0 + uTime * 2.5) *\n mix(0.0, 0.03, clamp(uIntensity, 0.0, 1.0));\n reflectUV.x += wave;\n reflectUV = clamp(reflectUV, 0.0, 1.0);\n vec4 reflectColor = texture2D(uTexture, reflectUV);\n float fade = smoothstep(0.5, 1.0, uv.y);\n reflectColor.rgb *= (1.0 - fade) * 0.9;\n reflectColor.a *= (1.0 - fade);\n gl_FragColor = reflectColor;\n }\n`;\n// Bouncing balls overlay.\nconst BOUNCING_BALLS_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n const int BALL_COUNT = 10;\n\n vec2 bounce(vec2 p) {\n return abs(fract(p) * 2.0 - 1.0);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 color = texture2D(uTexture, uv);\n\n float radius = mix(0.03, 0.07, clamp(uIntensity, 0.0, 1.0));\n float border = radius * 0.25;\n float ballsAlpha = 0.0;\n\n for (int i = 0; i < BALL_COUNT; i++) {\n float id = float(i) + 1.0;\n vec2 speed = vec2(0.3 + id * 0.12, 0.25 + id * 0.15);\n vec2 pos = bounce(vec2(uTime * speed.x + id * 0.17, uTime * speed.y + id * 0.29));\n float d = distance(uv, pos);\n float edge = smoothstep(radius, radius - border, d) -\n smoothstep(radius - border, radius - border - 0.01, d);\n ballsAlpha += edge;\n }\n\n ballsAlpha = clamp(ballsAlpha, 0.0, 1.0) * clamp(uIntensity, 0.0, 1.0);\n color.rgb = mix(color.rgb, vec3(1.0), ballsAlpha);\n gl_FragColor = color;\n }\n`;\n// Paper break / tear reveal style effect.\nconst PAPER_BREAK_REVEAL_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float noise(float x) {\n return sin(x * 28.0) * 0.035;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n\n float t = clamp(uTime, 0.0, 1.0);\n float cutCenter = 0.5;\n float wiggle = noise(uv.y + uTime * 3.0) * 0.2 * t;\n float tearLine = cutCenter + wiggle * clamp(uIntensity, 0.0, 1.0);\n\n float split = 0.3 * t * clamp(uIntensity, 0.0, 1.0);\n vec2 leftUV = uv;\n vec2 rightUV = uv;\n leftUV.x -= split * step(uv.x, tearLine);\n rightUV.x += split * step(tearLine, uv.x);\n leftUV = clamp(leftUV, 0.0, 1.0);\n rightUV = clamp(rightUV, 0.0, 1.0);\n\n vec4 left = texture2D(uTexture, leftUV);\n vec4 right = texture2D(uTexture, rightUV);\n float cutMask = smoothstep(tearLine - 0.02, tearLine + 0.02, uv.x);\n vec4 broken = mix(left, right, cutMask);\n\n float edge = smoothstep(0.0, 0.02, abs(uv.x - tearLine)) *\n (1.0 - smoothstep(0.02, 0.05, abs(uv.x - tearLine)));\n vec3 edgeColor = vec3(1.0) * edge * t;\n broken.rgb += edgeColor;\n\n gl_FragColor = mix(base, broken, t);\n }\n`;\n// Camera shake / move.\nconst CAMERA_MOVE_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(float x) {\n return fract(sin(x * 12.9898) * 43758.5453);\n }\n\n vec2 shakeOffset(float time, float intensity) {\n float x = (rand(time * 0.7) - 0.5) * intensity;\n float y = (rand(time * 1.3 + 10.0) - 0.5) * intensity;\n return vec2(x, y);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n float intensity = mix(0.0, 0.04, clamp(uIntensity, 0.0, 1.0));\n vec2 offset = shakeOffset(uTime * 2.0, intensity);\n vec2 uvMoved = clamp(uv + offset, 0.0, 1.0);\n vec4 color = texture2D(uTexture, uvMoved);\n gl_FragColor = color;\n }\n`;\n// Black flash pulses.\nconst BLACK_FLASH_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n float duration = 0.3;\n float m = mod(uTime, duration);\n float flash = smoothstep(0.0, duration * 0.5, m) *\n (1.0 - smoothstep(duration * 0.5, duration, m));\n flash *= clamp(uIntensity, 0.0, 1.0);\n vec3 color = mix(base.rgb, vec3(0.0), flash);\n gl_FragColor = vec4(color, base.a);\n }\n`;\n// Bright pulse + slight blur.\nconst BRIGHT_PULSE_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n vec4 blur3(sampler2D tex, vec2 uv, vec2 texel) {\n vec4 c = vec4(0.0);\n c += texture2D(tex, uv + texel * vec2(-1.0, -1.0)) * 0.0625;\n c += texture2D(tex, uv + texel * vec2( 0.0, -1.0)) * 0.125;\n c += texture2D(tex, uv + texel * vec2( 1.0, -1.0)) * 0.0625;\n c += texture2D(tex, uv + texel * vec2(-1.0, 0.0)) * 0.125;\n c += texture2D(tex, uv) * 0.25;\n c += texture2D(tex, uv + texel * vec2( 1.0, 0.0)) * 0.125;\n c += texture2D(tex, uv + texel * vec2(-1.0, 1.0)) * 0.0625;\n c += texture2D(tex, uv + texel * vec2( 0.0, 1.0)) * 0.125;\n c += texture2D(tex, uv + texel * vec2( 1.0, 1.0)) * 0.0625;\n return c;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec2 texel = vec2(1.0 / 1024.0);\n float pulse = 0.5 + 0.5 * sin(uTime * 3.0);\n float scale = 1.0 + pulse * 0.3 * clamp(uIntensity, 0.0, 1.0);\n vec2 center = vec2(0.5, 0.5);\n vec2 uvScaled = (uv - center) / scale + center;\n uvScaled = clamp(uvScaled, 0.0, 1.0);\n vec4 base = texture2D(uTexture, uvScaled);\n vec4 blurred = blur3(uTexture, uvScaled, texel * 1.5);\n vec4 colorValue = mix(base, blurred, 0.7 * clamp(uIntensity, 0.0, 1.0));\n gl_FragColor = colorValue;\n }\n`;\n// Random accent blobs with two colors.\nconst RANDOM_ACCENTS_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n }\n\n vec3 accentColor(float h) {\n vec3 colorA = vec3(1.0, 0.2, 0.6);\n vec3 colorB = vec3(0.2, 0.8, 1.0);\n return mix(colorA, colorB, fract(h * 7.0));\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n float density = mix(10.0, 25.0, clamp(uIntensity, 0.0, 1.0));\n vec2 gridUV = floor(uv * density);\n float h = hash(gridUV);\n\n vec2 offset = vec2(fract(h * 13.3), fract(h * 7.7));\n vec2 accentUV = fract(uv * density) - offset;\n float dist = length(accentUV);\n float size = mix(0.2, 0.08, clamp(uIntensity, 0.0, 1.0));\n float accent = smoothstep(size, 0.0, dist);\n accent *= 0.6 + 0.4 * sin(uTime * 10.0 + h * 6.2831);\n vec3 color = accentColor(h) * accent * clamp(uIntensity, 0.0, 1.0);\n float alpha = accent;\n gl_FragColor = vec4(color + base.rgb, max(base.a, alpha));\n }\n`;\n// Graffiti spray + drips over the frame.\nconst GRAFFITI_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(vec2 st) {\n return fract(sin(dot(st, vec2(12.9898,78.233))) * 43758.5453123);\n }\n\n float noise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = rand(i);\n float b = rand(i + vec2(1.0, 0.0));\n float c = rand(i + vec2(0.0, 1.0));\n float d = rand(i + vec2(1.0, 1.0));\n vec2 u = f * f * (3.0 - 2.0 * f);\n return mix(a, b, u.x) +\n (c - a) * u.y * (1.0 - u.x) +\n (d - b) * u.x * u.y;\n }\n\n float spray(vec2 st, float radius) {\n float dist = length(st - vec2(0.28, 0.5));\n float base = smoothstep(radius, radius - 0.06, dist);\n float speckle =\n noise(st * 45.0 + uTime * 3.0) *\n noise(st * 90.0);\n return clamp(base + speckle * 0.7, 0.0, 1.0);\n }\n\n float drips(vec2 st, float mask) {\n float column = noise(vec2(st.x * 25.0, 0.0));\n float drip =\n smoothstep(0.3, 0.7, column) *\n smoothstep(0.1, 1.0, 1.0 - st.y);\n float flow =\n noise(vec2(st.x * 35.0, st.y * 6.0 + uTime * 2.5));\n return drip * flow * mask;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n vec3 graffitiColor = vec3(1.0, 0.0, 0.5);\n float reveal = clamp(uIntensity, 0.0, 1.0);\n float sprayMask = spray(uv, 0.35 * reveal);\n float dripMask = drips(uv, sprayMask) * reveal;\n float graffitiMask = clamp(sprayMask + dripMask * 1.3, 0.0, 1.0);\n vec3 graffiti = graffitiColor * graffitiMask;\n vec3 Color = base.rgb + graffiti;\n gl_FragColor = vec4(Color, base.a);\n }\n`;\nexport const EFFECTS = {\n sepia: {\n key: \"sepia\",\n label: \"Sepia\",\n description: \"Warm vintage sepia tone.\",\n fragment: SEPIA_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n vignette: {\n key: \"vignette\",\n label: \"Vignette\",\n description: \"Darken edges to focus center.\",\n fragment: VIGNETTE_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n pixelate: {\n key: \"pixelate\",\n label: \"Pixelate\",\n description: \"Blocky pixelation effect.\",\n fragment: PIXELATE_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n warp: {\n key: \"warp\",\n label: \"Warp\",\n description: \"Sinusoidal warp of the frame.\",\n fragment: WARP_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n glitch: {\n key: \"glitch\",\n label: \"Glitch\",\n description: \"RGB slice and noise glitch.\",\n fragment: GLITCH_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.6 } },\n },\n rgbShift: {\n key: \"rgbShift\",\n label: \"RGB Shift\",\n description: \"Chromatic aberration style RGB split.\",\n fragment: RGB_SHIFT_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n halftone: {\n key: \"halftone\",\n label: \"Halftone\",\n description: \"Animated halftone dot shading.\",\n fragment: HALFTONE_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n hueShift: {\n key: \"hueShift\",\n label: \"Hue Shift\",\n description: \"Animated hue rotation of colors.\",\n fragment: HUE_SHIFT_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n waveDistort: {\n key: \"waveDistort\",\n label: \"Wave Distort\",\n description: \"Horizontal wave distortion.\",\n fragment: WAVE_DISTORT_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n tvScanlines: {\n key: \"tvScanlines\",\n label: \"TV Scanlines\",\n description: \"Old TV scanlines with subtle noise.\",\n fragment: TV_SCANLINES_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n hdr: {\n key: \"hdr\",\n label: \"HDR Boost\",\n description: \"Exposure and contrast HDR-style boost.\",\n fragment: HDR_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n retro70s: {\n key: \"retro70s\",\n label: \"Retro 70s\",\n description: \"Grainy, faded, vignetted retro film look.\",\n fragment: RETRO_70S_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n bubbleSparkles: {\n key: \"bubbleSparkles\",\n label: \"Bubble Sparkles\",\n description: \"Floating bubble-like sparkles.\",\n fragment: BUBBLE_SPARKLES_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n heartSparkles: {\n key: \"heartSparkles\",\n label: \"Heart Sparkles\",\n description: \"Animated heart-shaped sparkles.\",\n fragment: HEART_SPARKLES_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.9 } },\n },\n butterflySparkles: {\n key: \"butterflySparkles\",\n label: \"Butterfly Sparkles\",\n description: \"Animated butterfly-shaped sparkles.\",\n fragment: BUTTERFLY_SPARKLES_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.9 } },\n },\n lightning: {\n key: \"lightning\",\n label: \"Lightning\",\n description: \"Radial lightning strike with flash.\",\n fragment: LIGHTNING_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n lightningVeins: {\n key: \"lightningVeins\",\n label: \"Lightning Veins\",\n description: \"Energy veins radiating from center.\",\n fragment: LIGHTNING_VEINS_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n sparks: {\n key: \"sparks\",\n label: \"Sparks\",\n description: \"Random colored sparks overlay.\",\n fragment: SPARKS_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.9 } },\n },\n laser: {\n key: \"laser\",\n label: \"Laser\",\n description: \"Horizontal laser beam across the frame.\",\n fragment: LASER_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n waterReflection: {\n key: \"waterReflection\",\n label: \"Water Reflection\",\n description: \"Water reflection in the lower half of the frame.\",\n fragment: WATER_REFLECTION_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n bouncingBalls: {\n key: \"bouncingBalls\",\n label: \"Bouncing Balls\",\n description: \"Bouncing light balls over the frame.\",\n fragment: BOUNCING_BALLS_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n paperBreakReveal: {\n key: \"paperBreakReveal\",\n label: \"Paper Break Reveal\",\n description: \"Tearing paper style reveal.\",\n fragment: PAPER_BREAK_REVEAL_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n cameraMove: {\n key: \"cameraMove\",\n label: \"Camera Move\",\n description: \"Camera shake / movement effect.\",\n fragment: CAMERA_MOVE_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n blackFlash: {\n key: \"blackFlash\",\n label: \"Black Flash\",\n description: \"Periodic flash to black.\",\n fragment: BLACK_FLASH_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n brightPulse: {\n key: \"brightPulse\",\n label: \"Bright Pulse\",\n description: \"Bright pulse with subtle blur.\",\n fragment: BRIGHT_PULSE_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n randomAccents: {\n key: \"randomAccents\",\n label: \"Random Accents\",\n description: \"Random colored accent blobs.\",\n fragment: RANDOM_ACCENTS_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n graffiti: {\n key: \"graffiti\",\n label: \"Graffiti\",\n description: \"Graffiti spray paint and drips.\",\n fragment: GRAFFITI_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n};\nexport function getEffectFragment(key) {\n if (key in EFFECTS)\n return EFFECTS[key].fragment;\n return undefined;\n}\nexport const EFFECT_OPTIONS = Object.values(EFFECTS).map((cfg) => ({\n key: cfg.key,\n label: cfg.label,\n description: cfg.description,\n}));\n//# sourceMappingURL=catalog.js.map","import { useMemo } from \"react\";\nimport { EffectElement, TrackElement, TIMELINE_ELEMENT_TYPE } from \"@twick/timeline\";\nimport type { EffectKey } from \"@twick/effects\";\n\nexport interface UseEffectPanelParams {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}\n\nexport interface UseEffectPanelResult {\n selectedEffectKey: EffectKey | null;\n handleAddEffect: (key: EffectKey) => void;\n handleUpdateEffect: (key: EffectKey) => void;\n}\n\nexport const useEffectPanel = ({\n selectedElement,\n addElement,\n updateElement,\n}: UseEffectPanelParams): UseEffectPanelResult => {\n const selectedEffectKey = useMemo<EffectKey | null>(() => {\n if (!selectedElement) return null;\n if (selectedElement.getType() !== TIMELINE_ELEMENT_TYPE.EFFECT) return null;\n const effectElement = selectedElement as unknown as EffectElement;\n const props = effectElement.getProps?.();\n const key = props?.effectKey as EffectKey | undefined;\n return key ?? null;\n }, [selectedElement]);\n\n const handleAddEffect = (key: EffectKey) => {\n const effect = new EffectElement(key);\n addElement(effect);\n };\n\n const handleUpdateEffect = (key: EffectKey) => {\n if (!selectedElement) return;\n if (selectedElement.getType() !== TIMELINE_ELEMENT_TYPE.EFFECT) return;\n const effectElement = selectedElement as unknown as EffectElement;\n effectElement.setEffectKey(key);\n updateElement(effectElement);\n };\n\n return {\n selectedEffectKey,\n handleAddEffect,\n handleUpdateEffect,\n };\n};\n\n","import { BASIC_VERTEX_SHADER, EFFECTS } from \"@twick/effects\";\nimport type { EffectKey } from \"@twick/effects\";\n\n/**\n * Lightweight singleton that renders effect previews into a single hidden\n * WebGL canvas and returns data URLs for use in <img> tags.\n *\n * This avoids creating one WebGL context per effect card and stays within\n * browser context limits.\n */\n\nlet canvas: HTMLCanvasElement | null = null;\nlet gl: WebGLRenderingContext | null = null;\n\nconst PREVIEW_WIDTH = 160;\nconst PREVIEW_HEIGHT = 90;\n\nconst cache = new Map<EffectKey, string>();\nconst pending = new Map<EffectKey, Promise<string>>();\n\nfunction ensureContext(): WebGLRenderingContext | null {\n if (typeof window === \"undefined\") return null;\n\n if (gl && canvas) {\n return gl;\n }\n\n canvas = document.createElement(\"canvas\");\n canvas.width = PREVIEW_WIDTH;\n canvas.height = PREVIEW_HEIGHT;\n canvas.style.position = \"absolute\";\n canvas.style.left = \"-9999px\";\n canvas.style.top = \"-9999px\";\n canvas.style.width = `${PREVIEW_WIDTH}px`;\n canvas.style.height = `${PREVIEW_HEIGHT}px`;\n canvas.style.pointerEvents = \"none\";\n canvas.style.opacity = \"0\";\n\n document.body.appendChild(canvas);\n\n gl =\n (canvas.getContext(\"webgl\", {\n preserveDrawingBuffer: true,\n }) as WebGLRenderingContext | null) ||\n (canvas.getContext(\"experimental-webgl\", {\n preserveDrawingBuffer: true,\n }) as WebGLRenderingContext | null);\n\n if (!gl) {\n // Cleanup if WebGL is unavailable\n canvas.remove();\n canvas = null;\n return null;\n }\n\n return gl;\n}\n\nfunction createShader(\n gl: WebGLRenderingContext,\n type: number,\n source: string,\n): WebGLShader | null {\n const shader = gl.createShader(type);\n if (!shader) return null;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n const ok = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n if (!ok) {\n gl.deleteShader(shader);\n return null;\n }\n\n return shader;\n}\n\nasync function renderEffectToDataUrl(effectKey: EffectKey): Promise<string> {\n const glCtx = ensureContext();\n if (!glCtx || !canvas) {\n return \"\";\n }\n\n const effect = EFFECTS[effectKey];\n if (!effect) return \"\";\n\n const vertexShader = createShader(glCtx, glCtx.VERTEX_SHADER, BASIC_VERTEX_SHADER);\n const fragmentShader = createShader(glCtx, glCtx.FRAGMENT_SHADER, effect.fragment);\n if (!vertexShader || !fragmentShader) {\n return \"\";\n }\n\n const program = glCtx.createProgram();\n if (!program) {\n glCtx.deleteShader(vertexShader);\n glCtx.deleteShader(fragmentShader);\n return \"\";\n }\n\n glCtx.attachShader(program, vertexShader);\n glCtx.attachShader(program, fragmentShader);\n glCtx.linkProgram(program);\n\n const linked = glCtx.getProgramParameter(program, glCtx.LINK_STATUS);\n if (!linked) {\n glCtx.deleteProgram(program);\n glCtx.deleteShader(vertexShader);\n glCtx.deleteShader(fragmentShader);\n return \"\";\n }\n\n glCtx.useProgram(program);\n\n const positionLocation = glCtx.getAttribLocation(program, \"a_position\");\n const texCoordLocation = glCtx.getAttribLocation(program, \"a_texCoord\");\n\n const positionBuffer = glCtx.createBuffer();\n glCtx.bindBuffer(glCtx.ARRAY_BUFFER, positionBuffer);\n const positions = new Float32Array([\n -1, -1,\n 1, -1,\n -1, 1,\n -1, 1,\n 1, -1,\n 1, 1,\n ]);\n glCtx.bufferData(glCtx.ARRAY_BUFFER, positions, glCtx.STATIC_DRAW);\n\n glCtx.enableVertexAttribArray(positionLocation);\n glCtx.vertexAttribPointer(positionLocation, 2, glCtx.FLOAT, false, 0, 0);\n\n const texCoordBuffer = glCtx.createBuffer();\n glCtx.bindBuffer(glCtx.ARRAY_BUFFER, texCoordBuffer);\n const texCoords = new Float32Array([\n 0, 0,\n 1, 0,\n 0, 1,\n 0, 1,\n 1, 0,\n 1, 1,\n ]);\n glCtx.bufferData(glCtx.ARRAY_BUFFER, texCoords, glCtx.STATIC_DRAW);\n\n glCtx.enableVertexAttribArray(texCoordLocation);\n glCtx.vertexAttribPointer(texCoordLocation, 2, glCtx.FLOAT, false, 0, 0);\n\n const texture = glCtx.createTexture();\n glCtx.bindTexture(glCtx.TEXTURE_2D, texture);\n const size = 64;\n const data = new Uint8Array(size * size * 4);\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n const i = (y * size + x) * 4;\n const fx = x / (size - 1);\n const fy = y / (size - 1);\n data[i + 0] = fx * 255;\n data[i + 1] = fy * 255;\n data[i + 2] = 200;\n data[i + 3] = 255;\n }\n }\n glCtx.texImage2D(\n glCtx.TEXTURE_2D,\n 0,\n glCtx.RGBA,\n size,\n size,\n 0,\n glCtx.RGBA,\n glCtx.UNSIGNED_BYTE,\n data,\n );\n glCtx.texParameteri(glCtx.TEXTURE_2D, glCtx.TEXTURE_MIN_FILTER, glCtx.LINEAR);\n glCtx.texParameteri(glCtx.TEXTURE_2D, glCtx.TEXTURE_MAG_FILTER, glCtx.LINEAR);\n glCtx.texParameteri(glCtx.TEXTURE_2D, glCtx.TEXTURE_WRAP_S, glCtx.CLAMP_TO_EDGE);\n glCtx.texParameteri(glCtx.TEXTURE_2D, glCtx.TEXTURE_WRAP_T, glCtx.CLAMP_TO_EDGE);\n\n const textureLocation = glCtx.getUniformLocation(program, \"uTexture\");\n if (textureLocation) {\n glCtx.uniform1i(textureLocation, 0);\n }\n\n const timeLocation = glCtx.getUniformLocation(program, \"uTime\");\n if (timeLocation) {\n glCtx.uniform1f(timeLocation, 1.0);\n }\n\n const intensityLocation = glCtx.getUniformLocation(program, \"uIntensity\");\n if (intensityLocation) {\n glCtx.uniform1f(intensityLocation, 0.9);\n }\n\n const resolutionLocation = glCtx.getUniformLocation(program, \"uResolution\");\n if (resolutionLocation) {\n glCtx.uniform2f(resolutionLocation, canvas.width, canvas.height);\n }\n\n glCtx.viewport(0, 0, canvas.width, canvas.height);\n glCtx.clearColor(0, 0, 0, 1);\n glCtx.clear(glCtx.COLOR_BUFFER_BIT);\n glCtx.drawArrays(glCtx.TRIANGLES, 0, 6);\n\n const url = canvas.toDataURL(\"image/png\");\n\n // Clean up per-render resources, keep context and canvas\n glCtx.deleteTexture(texture);\n glCtx.deleteBuffer(positionBuffer);\n glCtx.deleteBuffer(texCoordBuffer);\n glCtx.deleteProgram(program);\n glCtx.deleteShader(vertexShader);\n glCtx.deleteShader(fragmentShader);\n\n return url;\n}\n\nexport function getEffectPreviewForEffect(\n effectKey: EffectKey,\n): Promise<string> {\n if (cache.has(effectKey)) {\n return Promise.resolve(cache.get(effectKey) as string);\n }\n\n if (pending.has(effectKey)) {\n return pending.get(effectKey) as Promise<string>;\n }\n\n const promise = (async () => {\n const url = await renderEffectToDataUrl(effectKey);\n if (url) {\n cache.set(effectKey, url);\n }\n pending.delete(effectKey);\n return url;\n })();\n\n pending.set(effectKey, promise);\n return promise;\n}\n\n","import type { TrackElement } from \"@twick/timeline\";\nimport { EFFECT_OPTIONS } from \"@twick/effects\";\nimport type { EffectKey } from \"@twick/effects\";\nimport { useEffect, useState } from \"react\";\nimport { useEffectPanel } from \"../../hooks/use-effect-panel\";\nimport { getEffectPreviewForEffect } from \"../../helpers/effect-preview-manager\";\n\ninterface EffectStylePanelProps {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}\n\ninterface EffectPreviewProps {\n effectKey: EffectKey;\n label: string;\n}\n\nfunction EffectPreview({ effectKey, label }: EffectPreviewProps) {\n const [src, setSrc] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n getEffectPreviewForEffect(effectKey).then((url) => {\n if (!cancelled && url) {\n setSrc(url);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [effectKey]);\n\n if (!src) {\n return (\n <div className=\"effect-preview-box-inner flex items-center justify-center text-xs text-neutral-400\">\n {label}\n </div>\n );\n }\n\n return (\n <img\n src={src}\n alt={label}\n className=\"effect-preview-box-inner object-cover\"\n loading=\"lazy\"\n />\n );\n}\n\nexport function EffectStylePanel({\n selectedElement,\n addElement,\n updateElement,\n}: EffectStylePanelProps) {\n const { selectedEffectKey, handleAddEffect, handleUpdateEffect } =\n useEffectPanel({\n selectedElement,\n addElement,\n updateElement,\n });\n\n const handleClick = (key: EffectKey) => {\n if (selectedEffectKey) {\n handleUpdateEffect(key);\n } else {\n handleAddEffect(key);\n }\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Effect Style</div>\n <div className=\"panel-section\">\n <div className=\"effect-grid\">\n {EFFECT_OPTIONS.map((effect) => {\n const isSelected = effect.key === selectedEffectKey;\n return (\n <button\n key={effect.key}\n type=\"button\"\n className={`effect-preview-card${isSelected ? \" effect-preview-card-selected\" : \"\"}`}\n onClick={() => handleClick(effect.key)}\n >\n <div className=\"effect-preview-box\">\n <EffectPreview effectKey={effect.key} label={effect.label} />\n <div className=\"effect-preview-label\">{effect.label}</div>\n </div>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n );\n}\n\n","import type { TrackElement } from \"@twick/timeline\";\nimport { EffectStylePanel } from \"../panel/effect-style-panel\";\n\ninterface EffectStylePanelContainerProps {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}\n\nexport function EffectStylePanelContainer({\n selectedElement,\n addElement,\n updateElement,\n}: EffectStylePanelContainerProps) {\n return (\n <EffectStylePanel\n selectedElement={selectedElement}\n addElement={addElement}\n updateElement={updateElement}\n />\n );\n}\n\n","/**\n * CaptionsPanel Component\n *\n * A presentational panel for managing caption entries in the studio.\n * Renders a list of caption items, each with a text input and two actions:\n * Split and Delete. A single Add button appears below the list.\n *\n * State is controlled by the parent via props; this component is stateless.\n *\n * Entry shape (CaptionEntry):\n * - `s`: start time (seconds)\n * - `e`: end time (seconds)\n * - `t`: caption text\n *\n * Props:\n * - `captions`: CaptionEntry[] — ordered list of captions\n * - `addCaption()`: add a new caption at the end\n * - `splitCaption(index)`: split the caption at `index`\n * - `deleteCaption(index)`: remove the caption at `index`\n * - `updateCaption(index, caption)`: update the caption at `index`\n *\n * @component\n * @example\n * ```tsx\n * <CaptionsPanel\n * captions={captions}\n * addCaption={addCaption}\n * splitCaption={splitCaption}\n * deleteCaption={deleteCaption}\n * updateCaption={updateCaption}\n * />\n * ```\n */\n\nimport { Trash2, Scissors } from \"lucide-react\";\n\ninterface CaptionEntry {\n s: number;\n e: number;\n t: string;\n}\n\nconst formatTime = (seconds: number) => {\n if (!Number.isFinite(seconds) || seconds < 0) return \"0:00.00\";\n const totalMs = Math.round(seconds * 1000);\n const totalSeconds = Math.floor(totalMs / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const secs = totalSeconds % 60;\n const ms = Math.floor((totalMs % 1000) / 10);\n const pad = (n: number, l = 2) => String(n).padStart(l, \"0\");\n return `${minutes}:${pad(secs)}.${pad(ms)}`;\n};\n\nexport function CaptionsPanel({\n captions,\n addCaption,\n splitCaption,\n deleteCaption,\n updateCaption,\n}: {\n captions: CaptionEntry[];\n addCaption: () => void;\n splitCaption: (index: number) => void;\n deleteCaption: (index: number) => void;\n updateCaption: (index: number, caption: CaptionEntry) => void;\n}) {\n return (\n <div className=\"panel-container captions-panel\">\n {/* Header */}\n <div className=\"captions-panel-header\">\n <h3 className=\"panel-title\">Captions</h3>\n <div className=\"captions-panel-header-meta\">\n {captions.length === 0 ? (\n <span className=\"captions-panel-count\">No captions yet</span>\n ) : null}\n <button\n onClick={addCaption}\n className=\"btn-primary captions-panel-add-button\"\n title=\"Add caption\"\n >\n Add caption\n </button>\n </div>\n </div>\n\n {/* Caption list */}\n {captions.length === 0 ? (\n <div className=\"panel-section captions-panel-empty\">\n <p className=\"captions-panel-empty-title\">Start your first caption</p>\n <p className=\"captions-panel-empty-subtitle\">\n Use the button above to add the first caption block for the active track.\n </p>\n <button\n onClick={addCaption}\n className=\"btn-primary captions-panel-empty-button\"\n title=\"Add first caption\"\n >\n Add caption\n </button>\n </div>\n ) : (\n <div className=\"panel-section captions-panel-list\">\n {captions.map((caption, i) => {\n return (\n <div\n key={i}\n className=\"captions-panel-item\"\n >\n <div className=\"captions-panel-item-header\">\n <span className=\"captions-panel-time captions-panel-time-start\">\n {formatTime(caption.s)}\n </span>\n <span className=\"captions-panel-time captions-panel-time-end\">\n {formatTime(caption.e)}\n </span>\n </div>\n\n <div className=\"captions-panel-item-body\">\n <textarea\n placeholder=\"Enter caption text\"\n value={caption.t}\n onChange={(e) =>\n updateCaption(i, { ...caption, t: e.target.value })\n }\n className=\"input-dark captions-panel-textarea\"\n />\n <div className=\"captions-panel-actions\">\n <button\n onClick={() => splitCaption(i)}\n className=\"btn-ghost captions-panel-action-button\"\n title=\"Split caption at midpoint\"\n >\n <Scissors className=\"icon-sm\" />\n </button>\n <button\n onClick={() => deleteCaption(i)}\n className=\"btn-ghost captions-panel-action-button\"\n title=\"Delete caption\"\n >\n <Trash2\n className=\"icon-sm\"\n color=\"var(--color-red-500)\"\n />\n </button>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","import { CAPTION_STYLE, computeCaptionGeometry } from \"@twick/timeline\";\n\nconst HIGHLIGHT_BG_FONT_SIZE = 46;\nconst WORD_BY_WORD_FONT_SIZE = 46;\nconst WORD_BY_WORD_WITH_BG_FONT_SIZE = 46;\nconst OUTLINE_ONLY_FONT_SIZE = 42;\nconst SOFT_BOX_FONT_SIZE = 40;\n\nconst HIGHLIGHT_BG_GEOMETRY = computeCaptionGeometry(HIGHLIGHT_BG_FONT_SIZE, CAPTION_STYLE.WORD_BG_HIGHLIGHT);\nconst WORD_BY_WORD_GEOMETRY = computeCaptionGeometry(WORD_BY_WORD_FONT_SIZE, CAPTION_STYLE.WORD_BY_WORD);\nconst WORD_BY_WORD_WITH_BG_GEOMETRY = computeCaptionGeometry(WORD_BY_WORD_WITH_BG_FONT_SIZE, CAPTION_STYLE.WORD_BY_WORD_WITH_BG);\nconst OUTLINE_ONLY_GEOMETRY = computeCaptionGeometry(OUTLINE_ONLY_FONT_SIZE, CAPTION_STYLE.OUTLINE_ONLY);\nconst SOFT_BOX_GEOMETRY = computeCaptionGeometry(SOFT_BOX_FONT_SIZE, CAPTION_STYLE.SOFT_BOX);\n\nexport const CAPTION_PROPS = {\n [CAPTION_STYLE.WORD_BG_HIGHLIGHT]: {\n font: {\n size: HIGHLIGHT_BG_FONT_SIZE,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n },\n lineWidth: HIGHLIGHT_BG_GEOMETRY.lineWidth,\n rectProps: HIGHLIGHT_BG_GEOMETRY.rectProps,\n stroke: \"#000000\",\n fontWeight: 700,\n shadowOffset: [-1, 1],\n shadowColor: \"#000000\",\n },\n [CAPTION_STYLE.WORD_BY_WORD]: {\n font: {\n size: WORD_BY_WORD_FONT_SIZE,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n }, \n lineWidth: WORD_BY_WORD_GEOMETRY.lineWidth,\n rectProps: WORD_BY_WORD_GEOMETRY.rectProps,\n stroke: \"#000000\",\n shadowOffset: [-1, 1],\n shadowColor: \"#000000\",\n shadowBlur: 5,\n },\n [CAPTION_STYLE.WORD_BY_WORD_WITH_BG]: {\n font: {\n size: WORD_BY_WORD_WITH_BG_FONT_SIZE,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n },\n lineWidth: WORD_BY_WORD_WITH_BG_GEOMETRY.lineWidth,\n rectProps: WORD_BY_WORD_WITH_BG_GEOMETRY.rectProps,\n shadowOffset: [-1, 1],\n shadowColor: \"#000000\",\n shadowBlur: 5,\n },\n [CAPTION_STYLE.OUTLINE_ONLY]: {\n font: {\n size: OUTLINE_ONLY_FONT_SIZE,\n weight: 600,\n family: \"Arial\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#000000\",\n },\n lineWidth: OUTLINE_ONLY_GEOMETRY.lineWidth,\n rectProps: OUTLINE_ONLY_GEOMETRY.rectProps,\n stroke: \"#000000\",\n fontWeight: 600,\n shadowOffset: [0, 0],\n shadowColor: \"#000000\",\n shadowBlur: 0,\n },\n [CAPTION_STYLE.SOFT_BOX]: {\n font: {\n size: SOFT_BOX_FONT_SIZE,\n weight: 600,\n family: \"Montserrat\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#333333\",\n },\n lineWidth: SOFT_BOX_GEOMETRY.lineWidth,\n rectProps: SOFT_BOX_GEOMETRY.rectProps,\n stroke: \"#000000\",\n fontWeight: 600,\n shadowOffset: [-1, 1],\n shadowColor: \"rgba(0,0,0,0.3)\",\n shadowBlur: 3,\n },\n };","import { useState, useEffect, useRef } from \"react\";\nimport {\n CAPTION_STYLE,\n CaptionElement,\n Track,\n useTimelineContext,\n} from \"@twick/timeline\";\nimport { CAPTION_PROPS } from \"../helpers/constant\";\n\ninterface CaptionEntry {\n s: number;\n e: number;\n t: string;\n}\n\nexport const useCaptionsPanel = () => {\n const [captions, setCaptions] = useState<CaptionEntry[]>([]);\n const captionsTrack = useRef<Track | null>(null);\n const { editor } = useTimelineContext();\n\n const resolveCaptionTracks = (): Track[] => {\n return (editor.getTimelineData()?.tracks || []).filter(\n (track) => track.getType() === \"caption\"\n );\n };\n\n const fetchCaptions = async () => {\n const captionTracks = resolveCaptionTracks();\n const editorCaptionsTrack = captionTracks[0];\n\n if (!editorCaptionsTrack) {\n captionsTrack.current = null;\n setCaptions([]);\n return;\n }\n\n captionsTrack.current = editorCaptionsTrack;\n setCaptions(\n editorCaptionsTrack.getElements().map((element) => ({\n s: element.getStart(),\n e: element.getEnd(),\n t: (element as CaptionElement).getText(),\n }))\n );\n };\n\n useEffect(() => {\n fetchCaptions();\n }, []);\n\n const checkCaptionsTrack = () => {\n if (!captionsTrack.current) {\n captionsTrack.current = editor.addTrack(\"Caption\", \"caption\");\n const props: Record<string, any> = {\n capStyle: CAPTION_STYLE.WORD_BG_HIGHLIGHT,\n ...CAPTION_PROPS[CAPTION_STYLE.WORD_BG_HIGHLIGHT],\n x: 0,\n y: 200,\n applyToAll: true,\n };\n captionsTrack.current?.setProps(props);\n }\n };\n\n const addCaption = () => {\n const newCaption: CaptionEntry = { s: 0, e: 0, t: \"New Caption\" };\n if (captions.length > 0) {\n newCaption.s = captions[captions.length - 1].e;\n }\n newCaption.e = newCaption.s + 1;\n setCaptions([...captions, newCaption]);\n checkCaptionsTrack();\n const captionElement = new CaptionElement(\n newCaption.t,\n newCaption.s,\n newCaption.e\n );\n editor.addElementToTrack(captionsTrack.current as Track, captionElement);\n };\n\n const splitCaption = async (index: number) => {\n if (captionsTrack.current) {\n const element = captionsTrack.current.getElements()[\n index\n ] as CaptionElement;\n const splitResult = await editor.splitElement(\n element,\n element.getStart() + element.getDuration() / 2\n );\n if (splitResult.success) {\n fetchCaptions();\n }\n }\n };\n\n const deleteCaption = (index: number) => {\n setCaptions(captions.filter((_, i) => i !== index));\n if (captionsTrack.current) {\n editor.removeElement(captionsTrack.current.getElements()[index]);\n }\n };\n\n const updateCaption = (index: number, caption: CaptionEntry) => {\n setCaptions(captions.map((sub, i) => (i === index ? caption : sub)));\n if (captionsTrack.current) {\n const element = captionsTrack.current.getElements()[\n index\n ] as CaptionElement;\n element.setText(caption.t);\n editor.updateElement(element);\n }\n };\n\n return {\n captions,\n addCaption,\n splitCaption,\n deleteCaption,\n updateCaption,\n };\n};\n","import { CaptionsPanel } from \"../panel/captions-panel\";\nimport { useCaptionsPanel } from \"../../hooks/use-captions-panel\";\n\nexport function CaptionsPanelContainer() {\n const captionsPanelProps = useCaptionsPanel();\n return <CaptionsPanel {...captionsPanelProps} />;\n}","import React, { useState, useCallback, useEffect } from \"react\";\nimport { Size, TrackElement } from \"@twick/timeline\";\nimport { ImageElement, VideoElement } from \"@twick/timeline\";\nimport { useLivePlayerContext } from \"@twick/live-player\";\nimport type { StudioConfig } from \"../../types\";\nimport type { ModelInfo } from \"@twick/ai-models\";\n\nconst DEFAULT_IMAGE_DURATION = 5;\n\ninterface GenerateMediaPanelContainerProps {\n videoResolution: Size;\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n studioConfig?: StudioConfig;\n}\n\nexport function GenerateMediaPanelContainer({\n videoResolution,\n addElement,\n studioConfig,\n}: GenerateMediaPanelContainerProps): React.ReactElement {\n const { getCurrentTime } = useLivePlayerContext();\n const [tab, setTab] = useState<\"image\" | \"video\">(\"image\");\n const [prompt, setPrompt] = useState(\"\");\n const [selectedEndpointId, setSelectedEndpointId] = useState(\"\");\n const [isGenerating, setIsGenerating] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [status, setStatus] = useState<string | null>(null);\n\n const imageService = studioConfig?.imageGenerationService;\n const videoService = studioConfig?.videoGenerationService;\n const hasAnyService = !!imageService || !!videoService;\n\n const imageModels = imageService?.getAvailableModels?.() ?? [];\n const videoModels = videoService?.getAvailableModels?.() ?? [];\n const endpoints: ModelInfo[] = tab === \"image\" ? imageModels : videoModels;\n const defaultEndpointId = endpoints[0]?.endpointId ?? \"\";\n const selectedEndpoint =\n endpoints.find((endpoint: ModelInfo) => endpoint.endpointId === selectedEndpointId) ??\n endpoints[0];\n const selectedProvider = selectedEndpoint?.provider;\n\n useEffect(() => {\n if (!selectedEndpointId && defaultEndpointId) {\n setSelectedEndpointId(defaultEndpointId);\n }\n }, [tab, defaultEndpointId, selectedEndpointId]);\n\n const pollStatus = useCallback(\n async (requestId: string) => {\n const service = tab === \"image\" ? imageService : videoService;\n if (!service) return;\n\n const interval = setInterval(async () => {\n try {\n const result = await service.getRequestStatus(requestId);\n if (result.status === \"completed\" && result.url) {\n clearInterval(interval);\n setIsGenerating(false);\n setStatus(null);\n setError(null);\n const currentTime = getCurrentTime();\n const duration = result.duration ?? DEFAULT_IMAGE_DURATION;\n\n if (tab === \"image\") {\n const element = new ImageElement(result.url, videoResolution);\n element.setStart(currentTime);\n element.setEnd(currentTime + duration);\n addElement(element);\n } else {\n const element = new VideoElement(result.url, videoResolution);\n element.setStart(currentTime);\n element.setEnd(currentTime + duration);\n addElement(element);\n }\n } else if (result.status === \"failed\") {\n clearInterval(interval);\n setIsGenerating(false);\n setStatus(null);\n setError(result.error ?? \"Generation failed\");\n }\n } catch {\n // Keep polling\n }\n }, 3000);\n\n return () => clearInterval(interval);\n },\n [tab, imageService, videoService, getCurrentTime, videoResolution, addElement]\n );\n\n const handleGenerate = useCallback(async () => {\n if (!prompt.trim()) {\n setError(\"Enter a prompt\");\n return;\n }\n\n if (tab === \"image\" && !imageService) {\n setError(\"Image generation not configured\");\n return;\n }\n if (tab === \"video\" && !videoService) {\n setError(\"Video generation not configured\");\n return;\n }\n\n setIsGenerating(true);\n setError(null);\n setStatus(\"Starting...\");\n\n try {\n const endpointId = selectedEndpointId || defaultEndpointId;\n const provider = selectedProvider;\n\n if (!endpointId || !provider) {\n setError(\"No model is configured for this tab\");\n setIsGenerating(false);\n setStatus(null);\n return;\n }\n\n if (tab === \"image\" && imageService) {\n const requestId = await imageService.generateImage({\n provider,\n endpointId,\n prompt: prompt.trim(),\n });\n if (requestId) {\n setStatus(\"Generating image...\");\n pollStatus(requestId);\n }\n } else if (tab === \"video\" && videoService) {\n const requestId = await videoService.generateVideo({\n provider,\n endpointId,\n prompt: prompt.trim(),\n });\n if (requestId) {\n setStatus(\"Generating video (this may take several minutes)...\");\n pollStatus(requestId);\n }\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : \"Generation failed\";\n setError(msg);\n setIsGenerating(false);\n setStatus(null);\n }\n }, [\n tab,\n prompt,\n selectedEndpointId,\n defaultEndpointId,\n imageService,\n videoService,\n pollStatus,\n selectedProvider,\n ]);\n\n if (!hasAnyService) {\n return (\n <div className=\"panel-container\">\n <p className=\"empty-state-text\">\n Image and video generation require configuration. Add imageGenerationService\n and videoGenerationService to StudioConfig.\n </p>\n </div>\n );\n }\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-section\">\n <div className=\"flex gap-2 mb-2\">\n <button\n type=\"button\"\n className={`btn-ghost ${tab === \"image\" ? \"active\" : \"\"}`}\n onClick={() => setTab(\"image\")}\n disabled={!imageService}\n >\n Image\n </button>\n <button\n type=\"button\"\n className={`btn-ghost ${tab === \"video\" ? \"active\" : \"\"}`}\n onClick={() => setTab(\"video\")}\n disabled={!videoService}\n >\n Video\n </button>\n </div>\n\n <div className=\"mb-2\">\n <label className=\"block text-sm mb-1\">Model</label>\n <select\n className=\"w-full p-2 border rounded\"\n value={selectedEndpointId}\n onChange={(e) => setSelectedEndpointId(e.target.value)}\n disabled={isGenerating}\n >\n {endpoints.map((ep: ModelInfo) => (\n <option key={ep.endpointId} value={ep.endpointId}>\n {ep.label}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"mb-2\">\n <label className=\"block text-sm mb-1\">Prompt</label>\n <textarea\n className=\"w-full p-2 border rounded min-h-[80px]\"\n value={prompt}\n onChange={(e) => setPrompt(e.target.value)}\n placeholder=\"Describe the image or video you want...\"\n disabled={isGenerating}\n />\n </div>\n\n {error && (\n <div className=\"mb-2 text-red-600 text-sm\">{error}</div>\n )}\n\n {status && (\n <div className=\"mb-2 text-sm text-gray-600\">{status}</div>\n )}\n\n <button\n type=\"button\"\n className=\"btn-primary w-full\"\n onClick={handleGenerate}\n disabled={isGenerating || !prompt.trim()}\n >\n {isGenerating ? \"Generating...\" : `Generate ${tab}`}\n </button>\n </div>\n </div>\n );\n}\n","import type { ProjectTemplate } from \"../types\";\nimport { TRACK_TYPES } from \"@twick/timeline\";\n\nexport const DEFAULT_PROJECT_TEMPLATES: ProjectTemplate[] = [\n {\n id: \"blank-project\",\n name: \"Blank Project\",\n description: \"Start from a clean timeline.\",\n category: \"blank\",\n project: {\n tracks: [],\n version: 1,\n metadata: {\n profile: \"default\",\n templateId: \"blank-project\",\n },\n },\n },\n {\n id: \"edu-lesson\",\n name: \"Lesson Template\",\n description: \"Intro, content, and summary sections for educational videos.\",\n category: \"edu\",\n project: {\n version: 1,\n backgroundColor: \"#0f172a\",\n metadata: {\n profile: \"edu\",\n templateId: \"edu-lesson\",\n chapters: [\n { id: \"chapter-intro\", title: \"Introduction\", time: 0 },\n { id: \"chapter-content\", title: \"Main Lesson\", time: 20 },\n { id: \"chapter-summary\", title: \"Summary\", time: 45 },\n ],\n },\n tracks: [\n {\n id: \"t-edu-text\",\n name: \"Lesson Text\",\n type: TRACK_TYPES.ELEMENT,\n elements: [\n {\n id: \"e-edu-title\",\n trackId: \"t-edu-text\",\n type: \"text\",\n name: \"Title\",\n s: 0,\n e: 6,\n props: {\n text: \"Lesson Title\",\n fontSize: 58,\n fill: \"#ffffff\",\n },\n },\n ],\n },\n ],\n },\n },\n {\n id: \"demo-screen\",\n name: \"Screen Demo\",\n description: \"Template optimized for product demonstrations.\",\n category: \"demo\",\n project: {\n version: 1,\n metadata: {\n profile: \"demo\",\n templateId: \"demo-screen\",\n },\n tracks: [\n {\n id: \"t-demo-video\",\n name: \"Screen Recording\",\n type: TRACK_TYPES.VIDEO,\n elements: [],\n },\n {\n id: \"t-demo-callout\",\n name: \"Callouts\",\n type: TRACK_TYPES.ELEMENT,\n elements: [],\n },\n ],\n },\n },\n];\n","import React from \"react\";\nimport { useTimelineContext, type ProjectJSON } from \"@twick/timeline\";\nimport { DEFAULT_PROJECT_TEMPLATES } from \"../../templates/default-templates\";\nimport type { ProjectTemplate, StudioConfig } from \"../../types\";\n\ninterface TemplateGalleryPanelProps {\n studioConfig?: StudioConfig;\n}\n\nexport const TemplateGalleryPanel = ({\n studioConfig,\n}: TemplateGalleryPanelProps): React.ReactElement => {\n const { editor } = useTimelineContext();\n const templates: ProjectTemplate[] =\n studioConfig?.templates?.length\n ? studioConfig.templates\n : DEFAULT_PROJECT_TEMPLATES;\n\n const loadTemplate = (project: ProjectJSON): void => {\n editor.loadProject(project);\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-header\">\n <h3>Templates</h3>\n </div>\n <div className=\"panel-content\" style={{ display: \"grid\", gap: \"12px\" }}>\n {templates.map((template) => (\n <button\n key={template.id}\n className=\"toolbar-btn\"\n onClick={() => loadTemplate(template.project)}\n style={{\n width: \"100%\",\n justifyContent: \"flex-start\",\n textAlign: \"left\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n padding: \"12px\",\n height: \"auto\",\n }}\n >\n <span style={{ fontWeight: 600 }}>{template.name}</span>\n <span style={{ opacity: 0.8, fontSize: \"12px\" }}>\n {template.description}\n </span>\n <span style={{ opacity: 0.6, fontSize: \"11px\", marginTop: \"2px\" }}>\n {template.category}\n </span>\n </button>\n ))}\n </div>\n </div>\n );\n};\n","import { useRef, useState } from \"react\";\n\ntype RecorderState = \"idle\" | \"recording\" | \"stopped\" | \"error\";\n\ninterface UseScreenRecorderReturn {\n state: RecorderState;\n mediaUrl: string | null;\n error: string | null;\n startRecording: (withMic: boolean) => Promise<void>;\n stopRecording: () => void;\n clearRecording: () => void;\n}\n\nexport const useScreenRecorder = (): UseScreenRecorderReturn => {\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const streamRef = useRef<MediaStream | null>(null);\n const chunksRef = useRef<BlobPart[]>([]);\n\n const [state, setState] = useState<RecorderState>(\"idle\");\n const [mediaUrl, setMediaUrl] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const cleanupStream = () => {\n streamRef.current?.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n };\n\n const startRecording = async (withMic: boolean) => {\n try {\n setError(null);\n if (mediaUrl) {\n URL.revokeObjectURL(mediaUrl);\n setMediaUrl(null);\n }\n\n const displayStream = await navigator.mediaDevices.getDisplayMedia({\n video: true,\n audio: true,\n });\n\n let mixedStream = displayStream;\n if (withMic) {\n const micStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n mixedStream = new MediaStream([\n ...displayStream.getVideoTracks(),\n ...displayStream.getAudioTracks(),\n ...micStream.getAudioTracks(),\n ]);\n }\n\n streamRef.current = mixedStream;\n chunksRef.current = [];\n const recorder = new MediaRecorder(mixedStream, {\n mimeType: \"video/webm\",\n });\n mediaRecorderRef.current = recorder;\n\n recorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n chunksRef.current.push(event.data);\n }\n };\n\n recorder.onerror = () => {\n setState(\"error\");\n setError(\"Recording failed\");\n };\n\n recorder.onstop = () => {\n const blob = new Blob(chunksRef.current, { type: \"video/webm\" });\n const url = URL.createObjectURL(blob);\n setMediaUrl(url);\n setState(\"stopped\");\n cleanupStream();\n };\n\n recorder.start();\n setState(\"recording\");\n } catch (err) {\n setState(\"error\");\n setError(err instanceof Error ? err.message : \"Unable to start recording\");\n cleanupStream();\n }\n };\n\n const stopRecording = () => {\n if (mediaRecorderRef.current && mediaRecorderRef.current.state !== \"inactive\") {\n mediaRecorderRef.current.stop();\n }\n };\n\n const clearRecording = () => {\n if (mediaUrl) {\n URL.revokeObjectURL(mediaUrl);\n }\n cleanupStream();\n setMediaUrl(null);\n setError(null);\n setState(\"idle\");\n };\n\n return {\n state,\n mediaUrl,\n error,\n startRecording,\n stopRecording,\n clearRecording,\n };\n};\n","import React, { useState } from \"react\";\nimport { VideoElement } from \"@twick/timeline\";\nimport type { PanelProps } from \"../../types\";\nimport { useScreenRecorder } from \"../../hooks/use-screen-recorder\";\n\nexport const RecordPanel = ({\n addElement,\n videoResolution,\n}: PanelProps): React.ReactElement => {\n const [withMic, setWithMic] = useState(true);\n const { state, mediaUrl, error, startRecording, stopRecording, clearRecording } =\n useScreenRecorder();\n\n const addToTimeline = async () => {\n if (!mediaUrl || !addElement) return;\n const element = new VideoElement(mediaUrl, videoResolution)\n .setEnd(5)\n .setName(\"Screen Recording\")\n .setMetadata({\n source: \"screen-recording\",\n hasMic: withMic,\n });\n await element.updateVideoMeta();\n const duration = element.getMediaDuration?.() ?? 5;\n element.setEnd(Math.max(1, duration));\n addElement(element);\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-header\">\n <h3>Record Screen</h3>\n </div>\n <div className=\"panel-content\" style={{ display: \"grid\", gap: \"12px\" }}>\n <label style={{ display: \"flex\", gap: \"8px\", alignItems: \"center\" }}>\n <input\n type=\"checkbox\"\n checked={withMic}\n onChange={(e) => setWithMic(e.target.checked)}\n />\n Include microphone\n </label>\n\n {state !== \"recording\" ? (\n <button className=\"btn-primary\" onClick={() => startRecording(withMic)}>\n Start Recording\n </button>\n ) : (\n <button className=\"btn-ghost\" onClick={stopRecording}>\n Stop Recording\n </button>\n )}\n\n {error ? <span className=\"text-sm\">{error}</span> : null}\n\n {mediaUrl ? (\n <>\n <video src={mediaUrl} controls style={{ width: \"100%\", borderRadius: \"8px\" }} />\n <button className=\"btn-primary\" onClick={addToTimeline}>\n Add Recording To Timeline\n </button>\n <button className=\"btn-ghost\" onClick={clearRecording}>\n Clear Recording\n </button>\n </>\n ) : null}\n </div>\n </div>\n );\n};\n","import React from \"react\";\nimport {\n ArrowElement,\n RectElement,\n CircleElement,\n LineElement,\n} from \"@twick/timeline\";\nimport type { PanelProps } from \"../../types\";\n\nconst SHAPE_COLORS = {\n line: \"#f97316\",\n arrow: \"#f59e0b\",\n rect: \"#facc15\",\n circle: \"#facc15\",\n};\n\nexport const AnnotationsPanel = ({\n addElement,\n videoResolution,\n}: PanelProps): React.ReactElement => {\n const addLine = async () => {\n if (!addElement) return;\n const element = new LineElement(SHAPE_COLORS.line, {\n width: Math.round(videoResolution.width * 0.35),\n height: 4,\n })\n .setEnd(5)\n .setName(\"Line\");\n await addElement(element);\n };\n\n const addArrow = async () => {\n if (!addElement) return;\n const element = new ArrowElement(SHAPE_COLORS.arrow, { width: 220, height: 20 })\n .setEnd(5)\n .setName(\"Arrow Callout\");\n await addElement(element);\n };\n\n const addBox = async () => {\n if (!addElement) return;\n const element = new RectElement(SHAPE_COLORS.rect, {\n width: Math.round(videoResolution.width * 0.35),\n height: Math.round(videoResolution.height * 0.18),\n })\n .setEnd(5)\n .setName(\"Box\");\n await addElement(element);\n };\n\n const addCircle = async () => {\n if (!addElement) return;\n const radius = Math.round(Math.min(videoResolution.width, videoResolution.height) * 0.12);\n const element = new CircleElement(SHAPE_COLORS.circle, radius)\n .setEnd(5)\n .setName(\"Circle\");\n await addElement(element);\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-header\">\n <h3>Shapes</h3>\n </div>\n <div\n className=\"panel-content\"\n style={{\n display: \"grid\",\n gap: \"12px\",\n gridTemplateColumns: \"repeat(auto-fit, minmax(140px, 1fr))\",\n }}\n >\n {/* Line */}\n <button\n type=\"button\"\n className=\"btn-ghost\"\n onClick={addLine}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n padding: \"10px 12px\",\n textAlign: \"left\",\n minHeight: 90,\n }}\n >\n <div\n style={{\n height: 6,\n borderRadius: 999,\n background: \"rgba(249,115,22,1)\",\n marginBottom: 8,\n }}\n />\n <div style={{ fontWeight: 600, marginBottom: 2 }}>Line</div>\n <div style={{ fontSize: 12, opacity: 0.8 }}>\n Draw a straight segment to connect or underline.\n </div>\n </button>\n\n {/* Arrow */}\n <button\n type=\"button\"\n className=\"btn-ghost\"\n onClick={addArrow}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n padding: \"10px 12px\",\n textAlign: \"left\",\n minHeight: 90,\n }}\n >\n <div\n style={{\n height: 10,\n borderRadius: 999,\n background: \"rgba(249,115,22,1)\",\n position: \"relative\",\n marginBottom: 8,\n }}\n >\n <div\n style={{\n position: \"absolute\",\n right: -4,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n width: 0,\n height: 0,\n borderTop: \"8px solid transparent\",\n borderBottom: \"8px solid transparent\",\n borderLeft: \"12px solid rgba(249,115,22,1)\",\n }}\n />\n </div>\n <div style={{ fontWeight: 600, marginBottom: 2 }}>Arrow callout</div>\n <div style={{ fontSize: 12, opacity: 0.8 }}>\n Emphasize a button or region with a directional arrow.\n </div>\n </button>\n\n {/* Box (Rect) */}\n <button\n type=\"button\"\n className=\"btn-ghost\"\n onClick={addBox}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n padding: \"10px 12px\",\n textAlign: \"left\",\n minHeight: 90,\n }}\n >\n <div\n style={{\n height: 40,\n borderRadius: 10,\n backgroundColor: \"rgba(250,204,21,0.35)\",\n border: \"1px solid rgba(250,204,21,0.8)\",\n marginBottom: 8,\n }}\n />\n <div style={{ fontWeight: 600, marginBottom: 2 }}>Box</div>\n <div style={{ fontSize: 12, opacity: 0.8 }}>\n Draw attention to important text or UI with a soft highlight.\n </div>\n </button>\n\n {/* Circle */}\n <button\n type=\"button\"\n className=\"btn-ghost\"\n onClick={addCircle}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n padding: \"10px 12px\",\n textAlign: \"left\",\n minHeight: 90,\n }}\n >\n <div\n style={{\n height: 40,\n width: 40,\n borderRadius: 999,\n border: \"2px solid rgba(250,204,21,0.9)\",\n backgroundColor: \"rgba(250,204,21,0.2)\",\n marginBottom: 8,\n alignSelf: \"flex-start\",\n }}\n />\n <div style={{ fontWeight: 600, marginBottom: 2 }}>Circle</div>\n <div style={{ fontSize: 12, opacity: 0.8 }}>\n Add a circular callout or highlight area.\n </div>\n </button>\n </div>\n </div>\n );\n};\n","import React, { useMemo, useState } from \"react\";\nimport { useTimelineContext, type ChapterMarker } from \"@twick/timeline\";\nimport { useLivePlayerContext } from \"@twick/live-player\";\nimport type { PanelProps } from \"../../types\";\n\nconst sortChapters = (chapters: ChapterMarker[]): ChapterMarker[] =>\n [...chapters].sort((a, b) => a.time - b.time);\n\nexport const ChaptersPanel = (_props: PanelProps): React.ReactElement => {\n const { editor, present } = useTimelineContext();\n const { getCurrentTime } = useLivePlayerContext();\n const [title, setTitle] = useState(\"\");\n\n const chapters = useMemo(\n () => sortChapters(present?.metadata?.chapters ?? []),\n [present?.metadata?.chapters]\n );\n\n const persistChapters = (nextChapters: ChapterMarker[]) => {\n const metadata = editor.getMetadata() ?? {};\n editor.setMetadata({\n ...metadata,\n chapters: sortChapters(nextChapters),\n });\n };\n\n const addChapter = () => {\n if (!title.trim()) return;\n const time = getCurrentTime();\n const next: ChapterMarker = {\n id: `chapter-${Date.now()}`,\n title: title.trim(),\n time,\n };\n persistChapters([...(chapters || []), next]);\n setTitle(\"\");\n };\n\n const removeChapter = (id: string) => {\n persistChapters(chapters.filter((chapter) => chapter.id !== id));\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-header\">\n <h3>Chapters</h3>\n </div>\n <div className=\"panel-content\" style={{ display: \"grid\", gap: \"10px\" }}>\n <input\n className=\"search-input\"\n placeholder=\"Chapter title at current playhead\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n />\n <button className=\"btn-primary\" onClick={addChapter}>\n Add Chapter At Playhead\n </button>\n <div style={{ display: \"grid\", gap: \"8px\" }}>\n {chapters.map((chapter) => (\n <div\n key={chapter.id}\n className=\"btn-ghost\"\n style={{\n width: \"100%\",\n height: \"auto\",\n justifyContent: \"space-between\",\n padding: \"8px 10px\",\n }}\n >\n <span>\n {Math.floor(chapter.time)}s - {chapter.title}\n </span>\n <button\n className=\"btn-ghost\"\n style={{ padding: \"2px 6px\" }}\n onClick={() => removeChapter(chapter.id)}\n >\n Remove\n </button>\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n};\n","import React, { useState } from \"react\";\nimport { TextElement, type ChapterMarker, useTimelineContext } from \"@twick/timeline\";\nimport type { PanelProps } from \"../../types\";\n\nconst parseSections = (script: string): string[] =>\n script\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => !!line);\n\nexport const ScriptPanel = ({ videoResolution }: PanelProps): React.ReactElement => {\n const [script, setScript] = useState(\"\");\n const { editor } = useTimelineContext();\n\n const buildTimelineFromScript = async () => {\n const sections = parseSections(script);\n if (!sections.length) return;\n\n const chapters: ChapterMarker[] = [];\n const track = editor.addTrack(\"Script Outline\", \"element\");\n\n for (let index = 0; index < sections.length; index++) {\n const section = sections[index];\n const start = index * 6;\n const end = start + 5;\n chapters.push({\n id: `script-chapter-${Date.now()}-${index}`,\n title: section,\n time: start,\n });\n const textElement = new TextElement(section)\n .setStart(start)\n .setEnd(end)\n .setName(`Script Section ${index + 1}`)\n .setPosition({\n x: Math.round(videoResolution.width / 2),\n y: Math.round(videoResolution.height * 0.2),\n });\n await editor.addElementToTrack(track, textElement);\n }\n\n const metadata = editor.getMetadata() ?? {};\n editor.setMetadata({\n ...metadata,\n chapters: [...(metadata.chapters ?? []), ...chapters],\n });\n editor.refresh();\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-header\">\n <h3>Script</h3>\n </div>\n <div className=\"panel-content\" style={{ display: \"grid\", gap: \"10px\" }}>\n <textarea\n className=\"input-dark\"\n rows={10}\n placeholder=\"Paste script outline (one section per line)\"\n value={script}\n onChange={(e) => setScript(e.target.value)}\n />\n <button className=\"btn-primary\" onClick={buildTimelineFromScript}>\n Generate Timeline From Outline\n </button>\n </div>\n </div>\n );\n};\n","import React from \"react\";\nimport { Size, TrackElement } from \"@twick/timeline\";\nimport type { StudioConfig, UploadConfig } from \"../../types\";\nimport { AudioPanelContainer } from \"./audio-panel-container\";\nimport { ImagePanelContainer } from \"./image-panel-container\";\nimport { VideoPanelContainer } from \"./video-panel-container\";\nimport { TextPanelContainer } from \"./text-panel-container\";\nimport { TextStylePanelContainer } from \"./text-style-panel-container\";\nimport { EffectStylePanelContainer } from \"./effect-style-panel-container\";\nimport { Wand2 } from \"lucide-react\";\nimport { CaptionsPanelContainer } from \"./captions-panel-container\";\nimport { GenerateMediaPanelContainer } from \"./generate-media-panel-container\";\nimport { TemplateGalleryPanel } from \"../panel/template-gallery-panel\";\nimport { RecordPanel } from \"../panel/record-panel\";\nimport { AnnotationsPanel } from \"../panel/annotations-panel\";\nimport { ChaptersPanel } from \"../panel/chapters-panel\";\nimport { ScriptPanel } from \"../panel/script-panel\";\n\n/**\n * Props interface for the ElementPanelContainer component.\n * Defines the configuration and callback functions for element management.\n */\ninterface ElementPanelContainerProps {\n selectedTool: string;\n selectedElement: TrackElement | null;\n videoResolution: Size;\n setSelectedTool: (tool: string) => void;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n uploadConfig?: UploadConfig;\n studioConfig?: StudioConfig;\n}\n\n/**\n * ElementPanelContainer component that renders the appropriate element panel\n * based on the currently selected tool. Provides a unified interface for\n * managing different types of timeline elements including media, text, shapes,\n * and captions. Shows an empty state when no tool is selected.\n *\n * @param props - Component props for element panel configuration\n * @returns JSX element containing the appropriate element panel or empty state\n * \n * @example\n * ```tsx\n * <ElementPanelContainer\n * selectedTool=\"text\"\n * selectedElement={currentElement}\n * videoResolution={{ width: 1920, height: 1080 }}\n * setSelectedTool={setTool}\n * addElement={addToTimeline}\n * updateElement={updateInTimeline}\n * />\n * ```\n */\nconst ElementPanelContainer = ({\n selectedTool,\n videoResolution,\n selectedElement,\n addElement,\n updateElement,\n setSelectedTool,\n uploadConfig,\n studioConfig,\n}: ElementPanelContainerProps): React.ReactElement => {\n const addNewElement = async (element: TrackElement) => {\n await addElement(element);\n };\n\n // Render appropriate library based on selected tool\n const renderLibrary = () => {\n const CustomPanel = studioConfig?.customPanels?.[selectedTool];\n if (CustomPanel) {\n return (\n <CustomPanel\n selectedElement={selectedElement}\n videoResolution={videoResolution}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n studioConfig={studioConfig}\n />\n );\n }\n\n switch (selectedTool) {\n case \"image\":\n return (\n <ImagePanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n />\n );\n case \"audio\":\n return (\n <AudioPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n />\n );\n case \"video\":\n return (\n <VideoPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n />\n );\n case \"text\":\n return (\n <TextPanelContainer\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"text-style\":\n return (\n <TextStylePanelContainer\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"effect\":\n return (\n <EffectStylePanelContainer\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"caption\":\n return <CaptionsPanelContainer />;\n case \"generate-media\":\n return (\n <GenerateMediaPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n studioConfig={studioConfig}\n />\n );\n case \"templates\":\n return <TemplateGalleryPanel studioConfig={studioConfig} />;\n case \"record\":\n return (\n <RecordPanel\n selectedElement={selectedElement}\n videoResolution={videoResolution}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n studioConfig={studioConfig}\n />\n );\n case \"shape\":\n return (\n <AnnotationsPanel\n selectedElement={selectedElement}\n videoResolution={videoResolution}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n studioConfig={studioConfig}\n />\n );\n case \"chapters\":\n return (\n <ChaptersPanel\n selectedElement={selectedElement}\n videoResolution={videoResolution}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n studioConfig={studioConfig}\n />\n );\n case \"script\":\n return (\n <ScriptPanel\n selectedElement={selectedElement}\n videoResolution={videoResolution}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n studioConfig={studioConfig}\n />\n );\n default:\n return (\n <div className=\"panel-container\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Wand2 className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">Select an element from toolbar</p>\n </div>\n </div>\n </div>\n );\n }\n };\n\n return renderLibrary();\n};\n\nexport default ElementPanelContainer;\n","import type { ReactNode } from \"react\";\n\ninterface PropertyRowProps {\n label: string;\n children: ReactNode;\n /** Optional secondary label/value on the right (e.g. units, current value) */\n secondary?: ReactNode;\n}\n\nexport function PropertyRow({ label, children, secondary }: PropertyRowProps) {\n return (\n <div className=\"property-row\">\n <div className=\"property-row-label\">\n <span className=\"property-label\">{label}</span>\n </div>\n <div className=\"property-row-control\">\n {children}\n </div>\n {secondary && (\n <div className=\"property-row-secondary\">\n {secondary}\n </div>\n )}\n </div>\n );\n}\n\n","import { ChevronDown, ChevronRight } from \"lucide-react\";\n\ninterface AccordionItemProps {\n title: string;\n icon: React.ReactNode;\n children: React.ReactNode;\n isOpen: boolean;\n onToggle: () => void;\n}\n\nexport function AccordionItem({ title, icon, children, isOpen, onToggle }: AccordionItemProps) {\n return (\n <div className=\"accordion-item\">\n <div\n onClick={onToggle}\n className=\"accordion-header\"\n >\n <div className=\"flex-container\">\n <div className=\"accent-purple\">\n {icon}\n </div>\n <span className=\"property-title\">{title}</span>\n </div>\n {isOpen ? (\n <ChevronDown className=\"icon-sm accent-purple\" />\n ) : (\n <ChevronRight className=\"icon-sm accent-purple\" />\n )}\n </div>\n <div\n className={`accordion-content ${isOpen ? 'expanded' : ''}`}\n >\n <div className=\"accordion-panel\">\n {children}\n </div>\n </div>\n </div>\n );\n}\n","import { RectElement, CircleElement, TrackElement } from \"@twick/timeline\";\n// Dimensions in inspector: Rect and Circle only. Image/Video resize via canvas (dimensions deferred).\nimport type { PropertiesPanelProps } from \"../../types\";\nimport { PropertyRow } from \"./property-row\";\nimport { Ruler } from \"lucide-react\";\nimport { AccordionItem } from \"../shared/accordion-item\";\nimport { useState } from \"react\";\n\nexport function ElementProps({ selectedElement, updateElement }: PropertiesPanelProps) {\n const opacity = selectedElement?.getOpacity() || 1;\n const rotation = selectedElement?.getRotation() || 0;\n const position = selectedElement?.getPosition() || { x: 0, y: 0 };\n\n const handleRotationChange = (rotation: number) => {\n if (selectedElement) {\n selectedElement.setRotation(rotation);\n updateElement?.(selectedElement as TrackElement);\n }\n }\n\n const handleOpacityChange = (opacity: number) => {\n if (selectedElement) {\n selectedElement.setOpacity(opacity);\n updateElement?.(selectedElement as TrackElement);\n }\n }\n const handlePositionChange = (props: Record<string, any>) => {\n if (selectedElement) {\n selectedElement.setPosition({ x: props.x ?? 0, y: props.y ?? 0 });\n updateElement?.(selectedElement as TrackElement);\n }\n }\n\n const handleDimensionsChange = (width?: number, height?: number) => {\n if (!selectedElement) return;\n if (selectedElement instanceof RectElement) {\n const size = selectedElement.getSize();\n selectedElement.setSize({ width: width ?? size.width, height: height ?? size.height });\n updateElement?.(selectedElement as TrackElement);\n } else if (selectedElement instanceof CircleElement) {\n const dims = {\n width: selectedElement.getRadius() * 2,\n height: selectedElement.getRadius() * 2,\n };\n const newDiameter =\n width !== undefined && width !== dims.width ? width : (height ?? dims.height);\n selectedElement.setRadius(newDiameter / 2);\n updateElement?.(selectedElement as TrackElement);\n }\n }\n\n const hasShapeDimensions =\n selectedElement instanceof RectElement || selectedElement instanceof CircleElement;\n\n let dimensions: { width: number; height: number } | null = null;\n if (selectedElement instanceof RectElement) {\n dimensions = selectedElement.getSize();\n } else if (selectedElement instanceof CircleElement) {\n const r = selectedElement.getRadius();\n dimensions = { width: r * 2, height: r * 2 };\n }\n\n const [isTransformOpen, setIsTransformOpen] = useState(false);\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Properties</div>\n\n <AccordionItem\n title=\"Transform\"\n icon={<Ruler className=\"icon-sm\" />}\n isOpen={isTransformOpen}\n onToggle={() => setIsTransformOpen((open) => !open)}\n >\n <div className=\"properties-group\">\n <div className=\"property-section\">\n <PropertyRow label=\"Position X\">\n <input\n type=\"number\"\n value={position.x ?? 0}\n onChange={(e) =>\n handlePositionChange({ x: Number(e.target.value) })\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n <PropertyRow label=\"Position Y\">\n <input\n type=\"number\"\n value={position.y ?? 0}\n onChange={(e) =>\n handlePositionChange({ y: Number(e.target.value) })\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n </div>\n\n {/* Dimensions - for rect, circle only; image/video resize via canvas */}\n {hasShapeDimensions && dimensions && (\n <div className=\"property-section\">\n <PropertyRow label=\"Width\">\n <input\n type=\"number\"\n min={1}\n value={Math.round(dimensions.width)}\n onChange={(e) =>\n handleDimensionsChange(\n Number(e.target.value),\n dimensions!.height\n )\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n <PropertyRow label=\"Height\">\n <input\n type=\"number\"\n min={1}\n value={Math.round(dimensions.height)}\n onChange={(e) =>\n handleDimensionsChange(\n dimensions!.width,\n Number(e.target.value)\n )\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n </div>\n )}\n\n {/* Opacity */}\n <div className=\"property-section\">\n <PropertyRow\n label=\"Opacity\"\n secondary={\n <span>\n {Math.round((opacity ?? 1) * 100)}\n %\n </span>\n }\n >\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n value={(opacity ?? 1) * 100}\n onChange={(e) =>\n handleOpacityChange(Number(e.target.value) / 100)\n }\n className=\"slider-purple\"\n />\n </PropertyRow>\n </div>\n\n {/* Rotation */}\n <div className=\"property-section\">\n <PropertyRow\n label=\"Rotation\"\n secondary={\n <span>\n {Math.round(rotation ?? 0)}\n °\n </span>\n }\n >\n <input\n type=\"range\"\n min=\"0\"\n max=\"360\"\n value={rotation ?? 0}\n onChange={(e) => handleRotationChange(Number(e.target.value))}\n className=\"slider-purple\"\n />\n </PropertyRow>\n </div>\n </div>\n </AccordionItem>\n </div>\n );\n}\n","import { TEXT_EFFECTS } from \"@twick/video-editor\";\nimport { ElementTextEffect, TextElement } from \"@twick/timeline\";\nimport type { PropertiesPanelProps } from \"../../types\";\nimport { AccordionItem } from \"../shared/accordion-item\";\nimport { PropertyRow } from \"./property-row\";\nimport { SparklesIcon } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport function TextEffects({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n if (!(selectedElement instanceof TextElement)) return null;\n\n const currentEffect = selectedElement.getTextEffect();\n\n const handleUpdateEffect = (props: {\n name?: string;\n delay?: number;\n duration?: number;\n bufferTime?: number;\n }) => {\n if (!selectedElement || !(selectedElement instanceof TextElement)) return;\n\n let effect = currentEffect;\n\n // If name is provided and empty, remove effect\n if (props.name === \"\") {\n selectedElement.setTextEffect(undefined);\n updateElement?.(selectedElement);\n return;\n }\n\n // Create new effect if none exists or name is changing\n if (!effect || (props.name && props.name !== effect.getName())) {\n effect = new ElementTextEffect(\n props.name || currentEffect?.getName() || TEXT_EFFECTS[0].name\n );\n // Set default values for new effect\n effect.setDelay(0);\n effect.setDuration(1);\n effect.setBufferTime(0.1);\n }\n\n // Update effect properties\n if (props.delay !== undefined) effect.setDelay(props.delay);\n if (props.duration !== undefined) effect.setDuration(props.duration);\n if (props.bufferTime !== undefined) effect.setBufferTime(props.bufferTime);\n\n // Update element with new/modified effect\n selectedElement.setTextEffect(effect);\n updateElement?.(selectedElement);\n };\n\n const [isEffectsOpen, setIsEffectsOpen] = useState(false);\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Text Effects</div>\n <AccordionItem\n title=\"Effects\"\n icon={<SparklesIcon className=\"icon-sm\" />}\n isOpen={isEffectsOpen}\n onToggle={() => setIsEffectsOpen((open) => !open)}\n >\n <div className=\"properties-group\">\n {/* Text Effect Selection */}\n <div className=\"property-section\">\n <PropertyRow label=\"Preset\">\n <select\n value={currentEffect?.getName() || \"\"}\n onChange={(e) => handleUpdateEffect({ name: e.target.value })}\n className=\"select-dark w-full\"\n >\n <option value=\"\">No Effect</option>\n {TEXT_EFFECTS.map((effect) => (\n <option key={effect.name} value={effect.name}>\n {effect.name.charAt(0).toUpperCase() + effect.name.slice(1)}\n </option>\n ))}\n </select>\n </PropertyRow>\n </div>\n\n {/* Text Effect Options */}\n {currentEffect && (\n <>\n {/* Delay */}\n <div className=\"property-section\">\n <PropertyRow label=\"Delay (s)\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"5\"\n step=\"0.1\"\n value={currentEffect.getDelay() ?? 0}\n onChange={(e) =>\n handleUpdateEffect({ delay: Number(e.target.value) })\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n </div>\n\n {/* Duration */}\n <div className=\"property-section\">\n <PropertyRow label=\"Duration (s)\">\n <input\n type=\"number\"\n min=\"0.1\"\n max=\"10\"\n step=\"0.1\"\n value={currentEffect.getDuration() ?? 1}\n onChange={(e) =>\n handleUpdateEffect({ duration: Number(e.target.value) })\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n </div>\n\n {/* Buffer Time */}\n <div className=\"property-section\">\n <PropertyRow label=\"Buffer (s)\">\n <input\n type=\"number\"\n min=\"0.05\"\n max=\"1\"\n step=\"0.05\"\n value={currentEffect.getBufferTime() ?? 0.1}\n onChange={(e) =>\n handleUpdateEffect({\n bufferTime: Number(e.target.value),\n })\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n </div>\n </>\n )}\n </div>\n </AccordionItem>\n </div>\n );\n}\n","import { ANIMATIONS } from \"@twick/video-editor\";\nimport { ElementAnimation, TrackElement } from \"@twick/timeline\";\nimport type { PropertiesPanelProps } from \"../../types\";\n\nexport function Animation({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n if (!(selectedElement instanceof TrackElement)) return null;\n\n const currentAnimation = selectedElement?.getAnimation();\n\n const handleUpdateAnimation = (props: {\n name?: string;\n interval?: number;\n duration?: number;\n intensity?: number;\n animate?: \"enter\" | \"exit\" | \"both\";\n mode?: \"in\" | \"out\";\n direction?: \"up\" | \"down\" | \"left\" | \"right\" | \"center\";\n }) => {\n if (!selectedElement) return;\n\n let animation = currentAnimation;\n\n // If name is provided and empty, remove animation\n if (props.name === \"\") {\n selectedElement.setAnimation(undefined);\n updateElement?.(selectedElement);\n return;\n }\n\n // Find animation definition\n const animationDef = ANIMATIONS.find(\n (a) => a.name === (props.name || currentAnimation?.getName())\n );\n if (!animationDef) return;\n\n // Create new animation if none exists or name is changing\n if (!animation || (props.name && props.name !== animation.getName())) {\n animation = new ElementAnimation(\n props.name || currentAnimation?.getName() || ANIMATIONS[0].name\n );\n // Set default values for new animation\n animation.setInterval(animationDef.interval || 1);\n animation.setDuration(animationDef.duration || 1);\n animation.setIntensity(animationDef.intensity || 1);\n animation.setAnimate(animationDef.animate || \"enter\");\n if (animationDef.mode) animation.setMode(animationDef.mode);\n if (animationDef.direction)\n animation.setDirection(animationDef.direction);\n }\n\n // Update animation properties with validation\n if (props.interval !== undefined) {\n const [min, max] = animationDef.options?.interval || [0.1, 5];\n animation.setInterval(Math.min(Math.max(props.interval, min), max));\n }\n if (props.duration !== undefined) {\n const [min, max] = animationDef.options?.duration || [0.1, 5];\n animation.setDuration(Math.min(Math.max(props.duration, min), max));\n }\n if (props.intensity !== undefined) {\n const [min, max] = animationDef.options?.intensity || [0.1, 2];\n animation.setIntensity(Math.min(Math.max(props.intensity, min), max));\n }\n if (\n props.animate &&\n animationDef.options?.animate?.includes(props.animate)\n ) {\n animation.setAnimate(props.animate);\n }\n if (props.mode && animationDef.options?.mode?.includes(props.mode)) {\n animation.setMode(props.mode);\n }\n if (\n props.direction &&\n animationDef.options?.direction?.includes(props.direction)\n ) {\n animation.setDirection(props.direction);\n }\n\n // Update element with new/modified animation\n selectedElement.setAnimation(animation);\n updateElement?.(selectedElement);\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Animations</div>\n {/* Animation Selection */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Type</label>\n <select\n value={currentAnimation?.getName() || \"\"}\n onChange={(e) => handleUpdateAnimation({ name: e.target.value })}\n className=\"select-dark w-full\"\n >\n <option value=\"\">No Animation</option>\n {ANIMATIONS.map((animation) => (\n <option key={animation.name} value={animation.name}>\n {animation.name.charAt(0).toUpperCase() + animation.name.slice(1)}\n </option>\n ))}\n </select>\n </div>\n\n {/* Animation Options */}\n {currentAnimation && (\n <>\n {/* Get current animation definition */}\n {(() => {\n const animationDef = ANIMATIONS.find(\n (a) => a.name === currentAnimation.getName()\n );\n if (!animationDef || !animationDef.options) return null;\n\n return (\n <>\n {/* Animate */}\n {animationDef.options?.animate && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">When to Animate</label>\n <select\n value={currentAnimation.getAnimate()}\n onChange={(e) =>\n handleUpdateAnimation({\n animate: e.target.value as\n | \"enter\"\n | \"exit\"\n | \"both\",\n })\n }\n className=\"select-dark w-full\"\n >\n {animationDef.options?.animate.map((option) => (\n <option key={option} value={option}>\n {option.charAt(0).toUpperCase() + option.slice(1)}\n </option>\n ))}\n </select>\n </div>\n )}\n\n {/* Direction */}\n {animationDef.options?.direction && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Direction</label>\n <select\n value={currentAnimation.getDirection()}\n onChange={(e) =>\n handleUpdateAnimation({\n direction: e.target.value as\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | \"center\",\n })\n }\n className=\"select-dark w-full\"\n >\n {animationDef.options?.direction.map((option) => (\n <option key={option} value={option}>\n {option.charAt(0).toUpperCase() + option.slice(1)}\n </option>\n ))}\n </select>\n </div>\n )}\n\n {/* Mode */}\n {animationDef.options?.mode && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Mode</label>\n <select\n value={currentAnimation.getMode()}\n onChange={(e) =>\n handleUpdateAnimation({\n mode: e.target.value as \"in\" | \"out\",\n })\n }\n className=\"select-dark w-full\"\n >\n {animationDef.options?.mode.map((option) => (\n <option key={option} value={option}>\n {option.charAt(0).toUpperCase() + option.slice(1)}\n </option>\n ))}\n </select>\n </div>\n )}\n\n {/* Duration */}\n {animationDef.options?.duration && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Duration (seconds)</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min={animationDef.options?.duration[0]}\n max={animationDef.options?.duration[1]}\n step=\"0.1\"\n value={currentAnimation.getDuration()}\n onChange={(e) =>\n handleUpdateAnimation({\n duration: Number(e.target.value),\n })\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{currentAnimation.getDuration()}</span>\n </div>\n </div>\n )}\n\n {/* Interval */}\n {animationDef.options?.interval && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Interval (seconds)</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min={animationDef.options?.interval[0]}\n max={animationDef.options?.interval[1]}\n step=\"0.1\"\n value={currentAnimation.getInterval()}\n onChange={(e) =>\n handleUpdateAnimation({\n interval: Number(e.target.value),\n })\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{currentAnimation.getInterval()}</span>\n </div>\n </div>\n )}\n\n {/* Intensity */}\n {animationDef.options?.intensity && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Intensity</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min={animationDef.options?.intensity[0]}\n max={animationDef.options?.intensity[1]}\n step=\"0.1\"\n value={currentAnimation.getIntensity()}\n onChange={(e) =>\n handleUpdateAnimation({\n intensity: Number(e.target.value),\n })\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{currentAnimation.getIntensity()}</span>\n </div>\n </div>\n )}\n </>\n );\n })()}\n </>\n )}\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport {\n CaptionElement,\n CAPTION_STYLE,\n CAPTION_STYLE_OPTIONS,\n computeCaptionGeometry,\n useTimelineContext,\n} from \"@twick/timeline\";\nimport { AVAILABLE_TEXT_FONTS } from \"@twick/video-editor\";\nimport { PropertiesPanelProps } from \"../../types\";\n\nexport { CAPTION_STYLE, CAPTION_STYLE_OPTIONS };\n\nexport const CAPTION_FONT = {\n size: 40,\n family: \"Bangers\",\n};\n\nexport const CAPTION_COLOR = {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#8C52FF\",\n outlineColor: \"#000000\",\n};\n\ntype CaptionColorKey = keyof typeof CAPTION_COLOR;\n\ntype CaptionStyleColorMeta = {\n usedColors: CaptionColorKey[];\n labels: Partial<Record<CaptionColorKey, string>>;\n};\n\ntype CaptionColorsState = {\n text: string;\n highlight?: string;\n bgColor?: string;\n outlineColor?: string;\n};\n\nconst CAPTION_STYLE_COLOR_META: Record<string, CaptionStyleColorMeta> = {\n // Word background highlight - white text on colored pill\n highlight_bg: {\n // Text color, and background pill color used in animation.\n usedColors: [\"text\", \"bgColor\"],\n labels: {\n text: \"Text Color\",\n bgColor: \"Highlight Background\",\n },\n },\n // Simple word-by-word – text only\n word_by_word: {\n // Visualizer uses text as fill + outlineColor for stroke, and highlight for active word.\n usedColors: [\"text\", \"highlight\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Word-by-word with a phrase bar background\n word_by_word_with_bg: {\n // Text color (fill), highlight for active word, outlineColor (stroke), bgColor used by phrase rect.\n usedColors: [\"text\", \"highlight\", \"bgColor\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n bgColor: \"Bar Background\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Classic outlined text\n outline_only: {\n // Outline-only style: fill + outline color; highlight not used in animation.\n usedColors: [\"text\", \"outlineColor\"],\n labels: {\n text: \"Fill Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Soft rounded box behind text\n soft_box: {\n usedColors: [\"text\", \"bgColor\", \"highlight\", \"outlineColor\", ],\n labels: {\n text: \"Text Color\",\n highlight: \"Highlight Color\",\n bgColor: \"Box Background\",\n outlineColor: \"Outline Color\",\n },\n },\n // Broadcast style lower-third bar\n lower_third: {\n // Title text, bar background, highlight color and outline color.\n usedColors: [\"text\", \"bgColor\", \"outlineColor\"],\n labels: {\n text: \"Title Text Color\",\n bgColor: \"Bar Background\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Typewriter – text only\n typewriter: {\n // Text color and outline color (stroke) used by visualizer; highlight not animated.\n usedColors: [\"text\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Karaoke – base text plus active word highlight\n karaoke: {\n // Base text color, active word highlight color, outline color.\n usedColors: [\"text\", \"highlight\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Karaoke-word – single active word, previous words dimmed\n \"karaoke-word\": {\n // Same color needs as karaoke.\n usedColors: [\"text\", \"highlight\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Pop / scale – text only\n pop_scale: {\n // Text color, highlight color for active word, and outline color; no background.\n usedColors: [\"text\", \"highlight\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n};\n\nconst DEFAULT_COLOR_META: CaptionStyleColorMeta = {\n usedColors: [\"text\", \"bgColor\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n bgColor: \"Background Color\",\n outlineColor: \"Outline Color\",\n },\n};\n\nconst CAPTION_FONTS = Object.values(AVAILABLE_TEXT_FONTS);\n\ninterface CaptionPropPanelProps {\n /** No-op when using fixed config. Kept for API compatibility. */\n setApplyPropsToAllCaption?: (apply: boolean) => void;\n}\n\nexport function CaptionPropPanel({\n selectedElement,\n updateElement,\n}: CaptionPropPanelProps & PropertiesPanelProps) {\n const { editor, changeLog } = useTimelineContext();\n const captionRef = useRef<HTMLInputElement>(null);\n const [capStyle, setCapStyle] = useState<(typeof CAPTION_STYLE_OPTIONS)[keyof typeof CAPTION_STYLE_OPTIONS]>(\n CAPTION_STYLE_OPTIONS[CAPTION_STYLE.WORD_BG_HIGHLIGHT]\n );\n const [fontSize, setFontSize] = useState(CAPTION_FONT.size);\n const [fontFamily, setFontFamily] = useState(CAPTION_FONT.family);\n const [colors, setColors] = useState<CaptionColorsState>({\n text: CAPTION_COLOR.text,\n highlight: CAPTION_COLOR.highlight,\n bgColor: CAPTION_COLOR.bgColor,\n outlineColor: CAPTION_COLOR.outlineColor,\n });\n const [useHighlight, setUseHighlight] = useState(true);\n const [useOutline, setUseOutline] = useState(true);\n\n const track = selectedElement instanceof CaptionElement\n ? editor.getTrackById(selectedElement.getTrackId())\n : null;\n const trackProps = track?.getProps() ?? {};\n const applyToAll = trackProps?.applyToAll ?? false;\n\n const handleUpdateCaption = (updates: {\n text?: string;\n style?: string;\n fontSize?: number;\n fontFamily?: string;\n colors?: CaptionColorsState;\n useHighlightOverride?: boolean;\n useOutlineOverride?: boolean;\n }) => {\n const captionElement = selectedElement as CaptionElement;\n if (!captionElement) return;\n\n const nextFontSize = updates.fontSize ?? fontSize;\n const geometry = computeCaptionGeometry(nextFontSize, updates.style ?? capStyle?.value ?? \"\");\n\n // Decide which colors to persist based on highlight toggle.\n const highlightEnabled = updates.useHighlightOverride ?? useHighlight;\n const outlineEnabled = updates.useOutlineOverride ?? useOutline;\n const rawNextColors: CaptionColorsState = updates.colors ?? colors;\n\n // Start with raw colors, then drop highlight / outlineColor keys when disabled.\n let effectiveColors: CaptionColorsState = { ...rawNextColors };\n if (!highlightEnabled) {\n const { highlight, ...rest } = effectiveColors;\n effectiveColors = rest;\n }\n if (!outlineEnabled) {\n const { outlineColor, ...rest } = effectiveColors;\n effectiveColors = rest;\n }\n\n if (applyToAll && track) {\n const nextFont = {\n size: nextFontSize,\n family: updates.fontFamily ?? fontFamily,\n };\n const nextColors = effectiveColors;\n const nextCapStyle = updates.style ?? capStyle?.value;\n\n track.setProps({\n ...trackProps,\n capStyle: nextCapStyle,\n font: { ...(trackProps?.font ?? {}), ...nextFont },\n colors: nextColors,\n lineWidth: geometry.lineWidth,\n rectProps: geometry.rectProps,\n });\n editor.refresh();\n } else {\n const elementProps = captionElement.getProps() ?? {};\n captionElement.setProps({\n ...elementProps,\n capStyle: updates.style ?? capStyle?.value,\n font: {\n size: nextFontSize,\n family: updates.fontFamily ?? fontFamily,\n },\n colors: effectiveColors,\n lineWidth: geometry.lineWidth,\n });\n updateElement?.(captionElement);\n }\n };\n\n useEffect(() => {\n const captionElement = selectedElement as CaptionElement;\n if (captionElement) {\n if (captionRef.current) {\n captionRef.current.value = captionElement?.getText();\n }\n const props = applyToAll ? trackProps : (captionElement.getProps() ?? {});\n const _capStyle = props?.capStyle;\n if (_capStyle && _capStyle in CAPTION_STYLE_OPTIONS) {\n setCapStyle(CAPTION_STYLE_OPTIONS[_capStyle as keyof typeof CAPTION_STYLE_OPTIONS]);\n }\n setFontSize(props?.font?.size ?? CAPTION_FONT.size);\n setFontFamily(props?.font?.family ?? CAPTION_FONT.family);\n const c = props?.colors;\n setColors({\n text: c?.text ?? CAPTION_COLOR.text,\n highlight: c?.highlight ?? CAPTION_COLOR.highlight,\n bgColor: c?.bgColor ?? CAPTION_COLOR.bgColor,\n outlineColor: c?.outlineColor ?? CAPTION_COLOR.outlineColor,\n });\n setUseHighlight(c?.highlight != null);\n setUseOutline(c?.outlineColor != null);\n }\n }, [selectedElement, applyToAll, changeLog]);\n\n if (!(selectedElement instanceof CaptionElement)) {\n return null;\n }\n\n const currentStyleKey = capStyle?.value as string | undefined;\n const currentColorMeta =\n (currentStyleKey && CAPTION_STYLE_COLOR_META[currentStyleKey]) ||\n DEFAULT_COLOR_META;\n\n const defaultColorLabels: Record<CaptionColorKey, string> = {\n text: \"Text Color\",\n bgColor: \"Background Color\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n };\n\n const renderColorControl = (key: CaptionColorKey) => {\n // Hide highlight / outline pickers entirely when disabled for this style.\n if (key === \"highlight\" && !useHighlight) {\n return null;\n }\n if (key === \"outlineColor\" && !useOutline) {\n return null;\n }\n const label = currentColorMeta.labels[key] ?? defaultColorLabels[key];\n const value = colors[key];\n\n const handleChange = (next: string) => {\n const nextColors = { ...colors, [key]: next };\n setColors(nextColors);\n handleUpdateCaption({ colors: nextColors });\n };\n\n if (value == null) {\n return null;\n }\n\n return (\n <div className=\"color-control\" key={key}>\n <label className=\"label-small\">{label}</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={value}\n onChange={(e) => handleChange(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={value}\n onChange={(e) => handleChange(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n );\n };\n\n return (\n <div className=\"panel-container\">\n {/* Caption Style */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Caption Style</label>\n <select\n value={capStyle.value}\n onChange={(e) => {\n const val = e.target.value as keyof typeof CAPTION_STYLE_OPTIONS;\n if (val in CAPTION_STYLE_OPTIONS) {\n setCapStyle(CAPTION_STYLE_OPTIONS[val]);\n }\n handleUpdateCaption({ style: e.target.value });\n }}\n className=\"select-dark w-full\"\n >\n {Object.values(CAPTION_STYLE_OPTIONS).map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Font Size */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Font Size</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"8\"\n max=\"72\"\n step=\"1\"\n value={fontSize}\n onChange={(e) => {\n const value = Number(e.target.value);\n setFontSize(value);\n handleUpdateCaption({ fontSize: value });\n }}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{fontSize}px</span>\n </div>\n </div>\n\n {/* Font */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Font</label>\n <select\n value={fontFamily}\n onChange={(e) => {\n const value = e.target.value;\n setFontFamily(value);\n handleUpdateCaption({ fontFamily: value });\n }}\n className=\"select-dark w-full\"\n >\n {CAPTION_FONTS.map((font) => (\n <option key={font} value={font}>\n {font}\n </option>\n ))}\n </select>\n </div>\n\n {/* Colors */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Colors</label>\n <div className=\"color-section\">\n {/* Highlight toggle only when style supports highlight color */}\n {currentColorMeta.usedColors.includes(\"highlight\") && (\n <div className=\"checkbox-control\">\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={useHighlight}\n onChange={(e) => {\n const enabled = e.target.checked;\n setUseHighlight(enabled);\n // Keep colors state typed (highlight is always a string in local state),\n // but when highlight is disabled we omit it when writing to timeline data.\n const nextColors = enabled\n ? { ...colors, highlight: colors.highlight || CAPTION_COLOR.highlight }\n : { ...colors };\n setColors(nextColors);\n handleUpdateCaption({\n colors: nextColors,\n useHighlightOverride: enabled,\n });\n }}\n className=\"checkbox-purple\"\n />\n Use Highlight Color\n </label>\n </div>\n )}\n {/* Outline toggle only when style supports outline color */}\n {currentColorMeta.usedColors.includes(\"outlineColor\") && (\n <div className=\"checkbox-control\">\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={useOutline}\n onChange={(e) => {\n const enabled = e.target.checked;\n setUseOutline(enabled);\n const nextColors = enabled\n ? {\n ...colors,\n outlineColor: colors.outlineColor || CAPTION_COLOR.outlineColor,\n }\n : { ...colors };\n setColors(nextColors);\n handleUpdateCaption({\n colors: nextColors,\n useOutlineOverride: enabled,\n });\n }}\n className=\"checkbox-purple\"\n />\n Use Outline Color\n </label>\n </div>\n )}\n {currentColorMeta.usedColors.map((key) => renderColorControl(key))}\n </div>\n </div>\n </div>\n );\n}\n\nexport default CaptionPropPanel;\n","/**\n * Volume conversion between linear (0-1) and dB scale.\n * Used for PlaybackPropsPanel to match professional audio tools (e.g. -60 dB to +6 dB).\n *\n * Formula: dB = 20 * log10(linear)\n * - 0 dB = 1.0 linear (full volume)\n * - -60 dB ≈ 0.001 linear (effectively mute)\n * - +6 dB ≈ 2.0 linear (amplification)\n */\n\nconst MIN_DB = -60;\nconst MAX_DB = 6;\n\n/**\n * Convert linear volume (0 to ~2) to dB.\n * Returns MIN_DB for linear <= 0 to avoid -Infinity.\n */\nexport function linearToDb(linear: number): number {\n if (linear <= 0) return MIN_DB;\n const db = 20 * Math.log10(linear);\n return Math.max(MIN_DB, Math.min(MAX_DB, db));\n}\n\n/**\n * Convert dB to linear volume.\n * Returns 0 for dB <= MIN_DB (mute).\n */\nexport function dbToLinear(db: number): number {\n if (db <= MIN_DB) return 0;\n const linear = Math.pow(10, db / 20);\n return Math.min(linear, Math.pow(10, MAX_DB / 20));\n}\n\nexport { MIN_DB, MAX_DB };\n","import { linearToDb, dbToLinear, MIN_DB, MAX_DB } from \"../../helpers/volume-db\";\nimport type { PropertiesPanelProps } from \"../../types\";\nimport { AccordionItem } from \"../shared/accordion-item\";\nimport { PropertyRow } from \"./property-row\";\nimport { Music2 } from \"lucide-react\";\nimport { useState } from \"react\";\n\nconst PLAYBACK_RATE_MIN = 0.25;\nconst PLAYBACK_RATE_MAX = 2;\nconst PLAYBACK_RATE_STEP = 0.25;\n\nexport function PlaybackPropsPanel({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n const elementProps = selectedElement?.getProps() || {};\n const volumeLinear = elementProps.volume ?? 1;\n const volumeDb = linearToDb(volumeLinear);\n const playbackRate = elementProps.playbackRate ?? 1;\n\n const handleUpdateElement = (props: Record<string, any>) => {\n if (selectedElement) {\n updateElement?.(selectedElement?.setProps({ ...elementProps, ...props }));\n }\n };\n\n const handleVolumeDbChange = (db: number) => {\n handleUpdateElement({ volume: dbToLinear(db) });\n };\n\n const handlePlaybackRateChange = (rate: number) => {\n handleUpdateElement({ playbackRate: rate });\n };\n\n const [isPlaybackOpen, setIsPlaybackOpen] = useState(false);\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Playback</div>\n <AccordionItem\n title=\"Playback\"\n icon={<Music2 className=\"icon-sm\" />}\n isOpen={isPlaybackOpen}\n onToggle={() => setIsPlaybackOpen((open) => !open)}\n >\n <div className=\"properties-group\">\n {/* Playback rate */}\n <div className=\"property-section\">\n <PropertyRow\n label=\"Playback rate\"\n secondary={<span>{playbackRate}×</span>}\n >\n <input\n type=\"range\"\n min={PLAYBACK_RATE_MIN}\n max={PLAYBACK_RATE_MAX}\n step={PLAYBACK_RATE_STEP}\n value={playbackRate}\n onChange={(e) =>\n handlePlaybackRateChange(Number(e.target.value))\n }\n className=\"slider-purple\"\n />\n </PropertyRow>\n </div>\n\n {/* Volume (dB) */}\n <div className=\"property-section\">\n <PropertyRow\n label=\"Volume\"\n secondary={\n <span>\n {volumeDb <= MIN_DB ? \"−∞\" : `${Math.round(volumeDb)} dB`}\n </span>\n }\n >\n <input\n type=\"range\"\n min={MIN_DB}\n max={MAX_DB}\n step={1}\n value={volumeDb}\n onChange={(e) =>\n handleVolumeDbChange(Number(e.target.value))\n }\n className=\"slider-purple\"\n />\n </PropertyRow>\n </div>\n </div>\n </AccordionItem>\n </div>\n );\n}\n","const imageDimensionsCache = {};\nconst videoMetaCache = {};\nconst audioDurationCache = {};\n\nconst getAudioDuration = (audioSrc) => {\n if (audioDurationCache[audioSrc]) {\n return Promise.resolve(audioDurationCache[audioSrc]);\n }\n return new Promise((resolve, reject) => {\n const audio = document.createElement(\"audio\");\n audio.preload = \"metadata\";\n const isSafeUrl = /^(https?:|blob:|data:audio\\/)/i.test(audioSrc);\n if (!isSafeUrl) {\n throw new Error(\"Unsafe audio source URL\");\n }\n audio.src = audioSrc;\n audio.onloadedmetadata = () => {\n const duration = audio.duration;\n audioDurationCache[audioSrc] = duration;\n resolve(duration);\n };\n audio.onerror = () => {\n reject(new Error(\"Failed to load audio metadata\"));\n };\n });\n};\n\nconst concurrencyLimit = 5;\nlet activeCount = 0;\nconst queue = [];\nfunction runNext() {\n if (queue.length === 0 || activeCount >= concurrencyLimit) return;\n const next = queue.shift();\n if (next) {\n activeCount++;\n next();\n }\n}\nfunction limit(fn) {\n return new Promise((resolve, reject) => {\n const task = () => {\n fn().then(resolve).catch(reject).finally(() => {\n activeCount--;\n runNext();\n });\n };\n if (activeCount < concurrencyLimit) {\n activeCount++;\n task();\n } else {\n queue.push(task);\n }\n });\n}\n\nconst loadImageDimensions = (url) => {\n return new Promise((resolve, reject) => {\n if (typeof document === \"undefined\") {\n reject(new Error(\"getImageDimensions() is only available in the browser.\"));\n return;\n }\n const img = new Image();\n img.onload = () => {\n resolve({ width: img.naturalWidth, height: img.naturalHeight });\n };\n img.onerror = reject;\n img.src = url;\n });\n};\nconst getImageDimensions = (url) => {\n if (imageDimensionsCache[url]) {\n return Promise.resolve(imageDimensionsCache[url]);\n }\n return limit(() => loadImageDimensions(url)).then((dimensions) => {\n imageDimensionsCache[url] = dimensions;\n return dimensions;\n });\n};\n\nconst getVideoMeta = (videoSrc) => {\n if (videoMetaCache[videoSrc]) {\n return Promise.resolve(videoMetaCache[videoSrc]);\n }\n return new Promise((resolve, reject) => {\n const isSafeUrl = /^(https?:|blob:|data:video\\/)/i.test(videoSrc);\n if (!isSafeUrl) {\n reject(new Error(\"Unsafe video source URL\"));\n return;\n }\n const tryLoadVideo = (useCors) => {\n const video = document.createElement(\"video\");\n video.preload = \"metadata\";\n video.crossOrigin = useCors ? \"anonymous\" : null;\n video.src = videoSrc;\n video.onloadedmetadata = () => {\n const meta = {\n width: video.videoWidth,\n height: video.videoHeight,\n duration: video.duration\n };\n videoMetaCache[videoSrc] = meta;\n resolve(meta);\n };\n video.onerror = () => {\n if (useCors) {\n video.src = \"\";\n tryLoadVideo(false);\n } else {\n reject(new Error(\"Failed to load video metadata. This may be due to CORS restrictions or an invalid video URL.\"));\n }\n };\n };\n tryLoadVideo(true);\n });\n};\n\nconst getThumbnail = async (videoUrl, seekTime = 0.1, playbackRate = 1) => {\n return new Promise((resolve, reject) => {\n const tryLoadThumbnail = (useCors) => {\n const video = document.createElement(\"video\");\n video.crossOrigin = useCors ? \"anonymous\" : null;\n video.muted = true;\n video.playsInline = true;\n video.autoplay = false;\n video.preload = \"auto\";\n video.playbackRate = playbackRate;\n video.style.position = \"absolute\";\n video.style.left = \"-9999px\";\n video.style.top = \"-9999px\";\n video.style.width = \"1px\";\n video.style.height = \"1px\";\n video.style.opacity = \"0\";\n video.style.pointerEvents = \"none\";\n video.style.zIndex = \"-1\";\n let timeoutId;\n const cleanup = () => {\n if (video.parentNode) video.remove();\n if (timeoutId) clearTimeout(timeoutId);\n };\n const handleError = () => {\n cleanup();\n if (useCors) {\n tryLoadThumbnail(false);\n } else {\n reject(new Error(`Failed to load video: ${video.error?.message || \"Unknown error. This may be due to CORS restrictions or an invalid video URL.\"}`));\n }\n };\n const handleSeeked = () => {\n try {\n video.pause();\n const canvas = document.createElement(\"canvas\");\n const width = video.videoWidth || 640;\n const height = video.videoHeight || 360;\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n cleanup();\n reject(new Error(\"Failed to get canvas context\"));\n return;\n }\n ctx.drawImage(video, 0, 0, width, height);\n try {\n const dataUrl = canvas.toDataURL(\"image/jpeg\", 0.8);\n cleanup();\n resolve(dataUrl);\n } catch {\n canvas.toBlob((blob) => {\n if (!blob) {\n cleanup();\n reject(new Error(\"Failed to create Blob\"));\n return;\n }\n const blobUrl = URL.createObjectURL(blob);\n cleanup();\n resolve(blobUrl);\n }, \"image/jpeg\", 0.8);\n }\n } catch (err) {\n cleanup();\n reject(new Error(`Error creating thumbnail: ${err}`));\n }\n };\n video.addEventListener(\"error\", handleError, { once: true });\n video.addEventListener(\"seeked\", handleSeeked, { once: true });\n video.addEventListener(\"loadedmetadata\", () => {\n const playPromise = video.play();\n if (playPromise !== void 0) {\n playPromise.then(() => {\n video.currentTime = seekTime || 0.1;\n }).catch(() => {\n video.currentTime = seekTime || 0.1;\n });\n } else {\n video.currentTime = seekTime || 0.1;\n }\n }, { once: true });\n timeoutId = window.setTimeout(() => {\n cleanup();\n reject(new Error(\"Video loading timed out\"));\n }, 15e3);\n video.src = videoUrl;\n document.body.appendChild(video);\n };\n tryLoadThumbnail(true);\n });\n};\n\nclass LRUCache {\n constructor(maxSize = 100) {\n if (maxSize <= 0) {\n throw new Error(\"maxSize must be greater than 0\");\n }\n this.maxSize = maxSize;\n this.cache = /* @__PURE__ */ new Map();\n }\n /**\n * Get a value from the cache.\n * Moves the item to the end (most recently used).\n */\n get(key) {\n const value = this.cache.get(key);\n if (value === void 0) {\n return void 0;\n }\n this.cache.delete(key);\n this.cache.set(key, value);\n return value;\n }\n /**\n * Set a value in the cache.\n * If cache is full, removes the least recently used item.\n */\n set(key, value) {\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n if (firstKey !== void 0) {\n this.cache.delete(firstKey);\n }\n }\n this.cache.set(key, value);\n }\n /**\n * Check if a key exists in the cache.\n */\n has(key) {\n return this.cache.has(key);\n }\n /**\n * Delete a key from the cache.\n */\n delete(key) {\n return this.cache.delete(key);\n }\n /**\n * Clear all entries from the cache.\n */\n clear() {\n this.cache.clear();\n }\n /**\n * Get the current size of the cache.\n */\n get size() {\n return this.cache.size;\n }\n}\n\nclass VideoFrameExtractor {\n constructor(options = {}) {\n this.frameCache = new LRUCache(\n options.maxCacheSize ?? 50\n );\n this.videoElements = /* @__PURE__ */ new Map();\n this.maxVideoElements = options.maxVideoElements ?? 5;\n this.loadTimeout = options.loadTimeout ?? 15e3;\n this.jpegQuality = options.jpegQuality ?? 0.8;\n this.playbackRate = options.playbackRate ?? 1;\n }\n /**\n * Get a frame thumbnail from a video at a specific time.\n * Uses caching and reuses video elements for optimal performance.\n * Uses 0.1s instead of 0 when seekTime is 0, since frames at t=0 are often blank.\n *\n * @param videoUrl - The URL of the video\n * @param seekTime - The time in seconds to extract the frame (0 is treated as 0.1)\n * @returns Promise resolving to a thumbnail image URL (data URL or blob URL)\n */\n async getFrame(videoUrl, seekTime = 0.1) {\n const effectiveSeekTime = seekTime === 0 ? 0.1 : seekTime;\n const cacheKey = this.getCacheKey(videoUrl, effectiveSeekTime);\n const cached = this.frameCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n const videoState = await this.getVideoElement(videoUrl);\n const thumbnail = await this.extractFrame(videoState.video, effectiveSeekTime);\n this.frameCache.set(cacheKey, thumbnail);\n return thumbnail;\n }\n /**\n * Get or create a video element for the given URL.\n * Reuses existing elements and manages cleanup.\n */\n async getVideoElement(videoUrl) {\n let videoState = this.videoElements.get(videoUrl);\n if (videoState && videoState.isReady) {\n videoState.lastUsed = Date.now();\n return videoState;\n }\n if (videoState && videoState.isLoading && videoState.loadPromise) {\n await videoState.loadPromise;\n if (videoState.isReady) {\n videoState.lastUsed = Date.now();\n return videoState;\n }\n }\n if (this.videoElements.size >= this.maxVideoElements) {\n this.cleanupOldVideoElements();\n }\n videoState = await this.createVideoElement(videoUrl);\n this.videoElements.set(videoUrl, videoState);\n videoState.lastUsed = Date.now();\n return videoState;\n }\n /**\n * Create and initialize a new video element.\n */\n async createVideoElement(videoUrl) {\n const video = document.createElement(\"video\");\n video.crossOrigin = \"anonymous\";\n video.muted = true;\n video.playsInline = true;\n video.autoplay = false;\n video.preload = \"auto\";\n video.playbackRate = this.playbackRate;\n video.style.position = \"absolute\";\n video.style.left = \"-9999px\";\n video.style.top = \"-9999px\";\n video.style.width = \"1px\";\n video.style.height = \"1px\";\n video.style.opacity = \"0\";\n video.style.pointerEvents = \"none\";\n video.style.zIndex = \"-1\";\n const state = {\n video,\n isReady: false,\n isLoading: true,\n loadPromise: null,\n lastUsed: Date.now()\n };\n state.loadPromise = new Promise((resolve, reject) => {\n let timeoutId;\n const cleanup = () => {\n if (timeoutId) clearTimeout(timeoutId);\n };\n const handleError = () => {\n cleanup();\n state.isLoading = false;\n reject(new Error(`Failed to load video: ${video.error?.message || \"Unknown error\"}`));\n };\n const handleLoadedMetadata = () => {\n cleanup();\n state.isReady = true;\n state.isLoading = false;\n resolve();\n };\n video.addEventListener(\"error\", handleError, { once: true });\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata, { once: true });\n timeoutId = window.setTimeout(() => {\n cleanup();\n state.isLoading = false;\n reject(new Error(\"Video loading timed out\"));\n }, this.loadTimeout);\n video.src = videoUrl;\n document.body.appendChild(video);\n });\n try {\n await state.loadPromise;\n } catch (error) {\n if (video.parentNode) {\n video.remove();\n }\n throw error;\n }\n return state;\n }\n /**\n * Extract a frame from a video at the specified time.\n */\n async extractFrame(video, seekTime) {\n return new Promise((resolve, reject) => {\n video.pause();\n const timeThreshold = 0.1;\n if (Math.abs(video.currentTime - seekTime) < timeThreshold) {\n try {\n const canvas = document.createElement(\"canvas\");\n const width = video.videoWidth || 640;\n const height = video.videoHeight || 360;\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"Failed to get canvas context\"));\n return;\n }\n ctx.drawImage(video, 0, 0, width, height);\n try {\n const dataUrl = canvas.toDataURL(\"image/jpeg\", this.jpegQuality);\n resolve(dataUrl);\n } catch {\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error(\"Failed to create Blob\"));\n return;\n }\n const blobUrl = URL.createObjectURL(blob);\n resolve(blobUrl);\n },\n \"image/jpeg\",\n this.jpegQuality\n );\n }\n return;\n } catch (err) {\n reject(new Error(`Error creating thumbnail: ${err}`));\n return;\n }\n }\n const handleSeeked = () => {\n try {\n const canvas = document.createElement(\"canvas\");\n const width = video.videoWidth || 640;\n const height = video.videoHeight || 360;\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"Failed to get canvas context\"));\n return;\n }\n ctx.drawImage(video, 0, 0, width, height);\n try {\n const dataUrl = canvas.toDataURL(\"image/jpeg\", this.jpegQuality);\n resolve(dataUrl);\n } catch {\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error(\"Failed to create Blob\"));\n return;\n }\n const blobUrl = URL.createObjectURL(blob);\n resolve(blobUrl);\n },\n \"image/jpeg\",\n this.jpegQuality\n );\n }\n } catch (err) {\n reject(new Error(`Error creating thumbnail: ${err}`));\n }\n };\n video.addEventListener(\"seeked\", handleSeeked, { once: true });\n const playPromise = video.play();\n if (playPromise !== void 0) {\n playPromise.then(() => {\n video.currentTime = seekTime;\n }).catch(() => {\n video.currentTime = seekTime;\n });\n } else {\n video.currentTime = seekTime;\n }\n });\n }\n /**\n * Generate cache key for a video URL and seek time.\n */\n getCacheKey(videoUrl, seekTime) {\n const roundedTime = Math.round(seekTime * 100) / 100;\n return `${videoUrl}:${roundedTime}`;\n }\n /**\n * Cleanup least recently used video elements.\n */\n cleanupOldVideoElements() {\n if (this.videoElements.size < this.maxVideoElements) {\n return;\n }\n const entries = Array.from(this.videoElements.entries());\n entries.sort((a, b) => a[1].lastUsed - b[1].lastUsed);\n const toRemove = entries.slice(0, entries.length - this.maxVideoElements + 1);\n for (const [url, state] of toRemove) {\n if (state.video.parentNode) {\n state.video.remove();\n }\n this.videoElements.delete(url);\n }\n }\n /**\n * Clear the frame cache.\n */\n clearCache() {\n this.frameCache.clear();\n }\n /**\n * Remove a specific video element and clear its cached frames.\n */\n removeVideo(videoUrl) {\n const state = this.videoElements.get(videoUrl);\n if (state) {\n if (state.video.parentNode) {\n state.video.remove();\n }\n this.videoElements.delete(videoUrl);\n }\n this.frameCache.clear();\n }\n /**\n * Dispose of all video elements and clear caches.\n * Removes all video elements from the DOM and clears both the frame cache\n * and video element cache. Call this when the extractor is no longer needed\n * to prevent memory leaks.\n */\n dispose() {\n for (const state of this.videoElements.values()) {\n if (state.video.parentNode) {\n state.video.remove();\n }\n }\n this.videoElements.clear();\n this.frameCache.clear();\n }\n}\nlet defaultExtractor = null;\nfunction getDefaultVideoFrameExtractor(options) {\n if (!defaultExtractor) {\n defaultExtractor = new VideoFrameExtractor(options);\n }\n return defaultExtractor;\n}\nasync function getThumbnailCached(videoUrl, seekTime = 0.1, playbackRate) {\n const extractor = getDefaultVideoFrameExtractor(\n playbackRate !== void 0 ? { playbackRate } : void 0\n );\n return extractor.getFrame(videoUrl, seekTime);\n}\n\nconst extractAudio = async ({\n src,\n playbackRate = 1,\n start = 0,\n end\n}) => {\n if (!src) throw new Error(\"src is required\");\n if (playbackRate <= 0) throw new Error(\"playbackRate must be > 0\");\n const isSafeUrl = /^(https?:|blob:|data:)/i.test(src);\n if (!isSafeUrl) throw new Error(\"Unsafe media source URL\");\n const audioBuffer = await fetchAndDecodeAudio(src);\n if (audioBuffer.duration === 0 || audioBuffer.length === 0) {\n throw new Error(\"No audio track found in the media source\");\n }\n if (isAudioSilent(audioBuffer)) {\n throw new Error(\"Audio track is silent (no audio content detected)\");\n }\n const clampedStart = Math.max(0, start || 0);\n const fullDuration = audioBuffer.duration;\n const clampedEnd = Math.min(\n typeof end === \"number\" ? end : fullDuration,\n fullDuration\n );\n if (clampedEnd <= clampedStart)\n throw new Error(\"Invalid range: end must be greater than start\");\n const renderedBuffer = await renderAudioSegment(\n audioBuffer,\n clampedStart,\n clampedEnd,\n playbackRate\n );\n const mp3Blob = await audioBufferToMp3(renderedBuffer);\n return URL.createObjectURL(mp3Blob);\n};\nconst hasAudio = async (src) => {\n if (!src) return false;\n const isSafeUrl = /^(https?:|blob:|data:)/i.test(src);\n if (!isSafeUrl) return false;\n try {\n const audioBuffer = await fetchAndDecodeAudio(src);\n if (audioBuffer.duration === 0 || audioBuffer.length === 0) {\n return false;\n }\n if (isAudioSilent(audioBuffer)) {\n return false;\n }\n return true;\n } catch (error) {\n return false;\n }\n};\nconst stitchAudio = async (segments, totalDuration) => {\n if (!segments || segments.length === 0) {\n throw new Error(\"At least one audio segment is required\");\n }\n const duration = totalDuration || Math.max(...segments.map((s) => s.e));\n const renderedBuffer = await createAudioTimeline(segments, duration);\n const mp3Blob = await audioBufferToMp3(renderedBuffer);\n return URL.createObjectURL(mp3Blob);\n};\nconst fetchAndDecodeAudio = async (src) => {\n const response = await fetch(src);\n if (!response.ok) throw new Error(`Failed to fetch source: ${response.status}`);\n const arrayBuffer = await response.arrayBuffer();\n return decodeAudioData(arrayBuffer);\n};\nconst decodeAudioData = async (arrayBuffer) => {\n const AudioContextCtor = window.AudioContext || window.webkitAudioContext;\n if (!AudioContextCtor) throw new Error(\"Web Audio API not supported\");\n const audioContext = new AudioContextCtor();\n try {\n return await new Promise((resolve, reject) => {\n audioContext.decodeAudioData(\n arrayBuffer.slice(0),\n (buf) => resolve(buf),\n (err) => reject(err || new Error(\"Failed to decode audio: no audio track found or unsupported format\"))\n );\n });\n } finally {\n audioContext.close();\n }\n};\nconst isAudioSilent = (buffer, threshold = 1e-3) => {\n for (let channel = 0; channel < buffer.numberOfChannels; channel++) {\n const channelData = buffer.getChannelData(channel);\n for (let i = 0; i < channelData.length; i += 100) {\n if (Math.abs(channelData[i]) > threshold) {\n return false;\n }\n }\n }\n return true;\n};\nconst renderAudioSegment = async (audioBuffer, start, end, playbackRate) => {\n const OfflineAudioContextCtor = window.OfflineAudioContext || window.webkitOfflineAudioContext;\n if (!OfflineAudioContextCtor) throw new Error(\"OfflineAudioContext not supported\");\n const sampleRate = audioBuffer.sampleRate;\n const numChannels = audioBuffer.numberOfChannels;\n const sourceDuration = end - start;\n const renderedFrames = Math.max(\n 1,\n Math.ceil(sourceDuration / playbackRate * sampleRate)\n );\n const offline = new OfflineAudioContextCtor(numChannels, renderedFrames, sampleRate);\n const sourceNode = offline.createBufferSource();\n sourceNode.buffer = audioBuffer;\n sourceNode.playbackRate.value = playbackRate;\n sourceNode.connect(offline.destination);\n sourceNode.start(0, start, sourceDuration);\n return await offline.startRendering();\n};\nconst createAudioTimeline = async (segments, duration) => {\n const OfflineAudioContextCtor = window.OfflineAudioContext || window.webkitOfflineAudioContext;\n if (!OfflineAudioContextCtor) throw new Error(\"OfflineAudioContext not supported\");\n const sampleRate = 44100;\n const totalFrames = Math.ceil(duration * sampleRate);\n const offline = new OfflineAudioContextCtor(2, totalFrames, sampleRate);\n for (const segment of segments) {\n if (segment.s >= segment.e) continue;\n const volume = segment.volume ?? 1;\n if (volume <= 0) continue;\n try {\n const audioBuffer = await fetchAndDecodeAudio(segment.src);\n const segmentDuration = segment.e - segment.s;\n const sourceDuration = Math.min(segmentDuration, audioBuffer.duration);\n const source = offline.createBufferSource();\n source.buffer = audioBuffer;\n if (volume !== 1) {\n const gainNode = offline.createGain();\n gainNode.gain.value = volume;\n source.connect(gainNode);\n gainNode.connect(offline.destination);\n } else {\n source.connect(offline.destination);\n }\n source.start(segment.s, 0, sourceDuration);\n } catch {\n }\n }\n return await offline.startRendering();\n};\nconst audioBufferToMp3 = async (buffer) => {\n try {\n const wavArrayBuffer = audioBufferToWavArrayBuffer(buffer);\n const pcmBuffer = await decodeAudioData(wavArrayBuffer);\n return await encodePcmToMp3(pcmBuffer);\n } catch (error) {\n return audioBufferToWavBlob(buffer);\n }\n};\nconst audioBufferToWavArrayBuffer = (buffer) => {\n const numChannels = buffer.numberOfChannels;\n const sampleRate = buffer.sampleRate;\n const numFrames = buffer.length;\n const interleaved = interleave(buffer, numChannels, numFrames);\n const bytesPerSample = 2;\n const blockAlign = numChannels * bytesPerSample;\n const byteRate = sampleRate * blockAlign;\n const dataSize = interleaved.length * bytesPerSample;\n const bufferSize = 44 + dataSize;\n const arrayBuffer = new ArrayBuffer(bufferSize);\n const view = new DataView(arrayBuffer);\n writeString(view, 0, \"RIFF\");\n view.setUint32(4, 36 + dataSize, true);\n writeString(view, 8, \"WAVE\");\n writeString(view, 12, \"fmt \");\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n view.setUint16(22, numChannels, true);\n view.setUint32(24, sampleRate, true);\n view.setUint32(28, byteRate, true);\n view.setUint16(32, blockAlign, true);\n view.setUint16(34, 16, true);\n writeString(view, 36, \"data\");\n view.setUint32(40, dataSize, true);\n floatTo16BitPCM(view, 44, interleaved);\n return arrayBuffer;\n};\nconst encodePcmToMp3 = async (buffer) => {\n const lamejs = await import('./index-CXhwwSX-.mjs').then(n => n.i);\n const channels = buffer.numberOfChannels >= 2 ? 2 : 1;\n const targetSampleRate = 22050;\n const downsampledBuffer = downsampleAudioBuffer(buffer, targetSampleRate);\n const kbps = 48;\n const mp3encoder = new lamejs.default.Mp3Encoder(channels, targetSampleRate, kbps);\n const samplesPerFrame = 1152;\n const leftFloat = downsampledBuffer.getChannelData(0);\n const left = floatTo16(leftFloat);\n let right;\n if (channels === 2) {\n const rightFloat = downsampledBuffer.getChannelData(1);\n right = floatTo16(rightFloat);\n }\n const mp3Chunks = [];\n for (let i = 0; i < left.length; i += samplesPerFrame) {\n const leftChunk = left.subarray(i, Math.min(i + samplesPerFrame, left.length));\n let mp3buf;\n if (channels === 2 && right) {\n const rightChunk = right.subarray(i, Math.min(i + samplesPerFrame, right.length));\n mp3buf = mp3encoder.encodeBuffer(leftChunk, rightChunk);\n } else {\n mp3buf = mp3encoder.encodeBuffer(leftChunk);\n }\n if (mp3buf.length > 0) mp3Chunks.push(mp3buf);\n }\n const end = mp3encoder.flush();\n if (end.length > 0) mp3Chunks.push(end);\n return new Blob(mp3Chunks, { type: \"audio/mpeg\" });\n};\nconst audioBufferToWavBlob = (buffer) => {\n const arrayBuffer = audioBufferToWavArrayBuffer(buffer);\n return new Blob([arrayBuffer], { type: \"audio/wav\" });\n};\nconst downsampleAudioBuffer = (buffer, targetSampleRate) => {\n if (buffer.sampleRate === targetSampleRate) {\n return buffer;\n }\n const ratio = buffer.sampleRate / targetSampleRate;\n const newLength = Math.round(buffer.length / ratio);\n const newBuffer = new AudioContext().createBuffer(\n buffer.numberOfChannels,\n newLength,\n targetSampleRate\n );\n for (let channel = 0; channel < buffer.numberOfChannels; channel++) {\n const oldData = buffer.getChannelData(channel);\n const newData = newBuffer.getChannelData(channel);\n for (let i = 0; i < newLength; i++) {\n const oldIndex = Math.floor(i * ratio);\n newData[i] = oldData[oldIndex];\n }\n }\n return newBuffer;\n};\nconst interleave = (buffer, numChannels, numFrames) => {\n if (numChannels === 1) {\n return buffer.getChannelData(0).slice(0, numFrames);\n }\n const result = new Float32Array(numFrames * numChannels);\n const channelData = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channelData[ch] = buffer.getChannelData(ch);\n }\n let writeIndex = 0;\n for (let i = 0; i < numFrames; i++) {\n for (let ch = 0; ch < numChannels; ch++) {\n result[writeIndex++] = channelData[ch][i];\n }\n }\n return result;\n};\nconst floatTo16BitPCM = (view, offset, input) => {\n let pos = offset;\n for (let i = 0; i < input.length; i++, pos += 2) {\n let s = Math.max(-1, Math.min(1, input[i]));\n view.setInt16(pos, s < 0 ? s * 32768 : s * 32767, true);\n }\n};\nconst floatTo16 = (input) => {\n const output = new Int16Array(input.length);\n for (let i = 0; i < input.length; i++) {\n const s = Math.max(-1, Math.min(1, input[i]));\n output[i] = s < 0 ? s * 32768 : s * 32767;\n }\n return output;\n};\nconst writeString = (view, offset, str) => {\n for (let i = 0; i < str.length; i++) {\n view.setUint8(offset + i, str.charCodeAt(i));\n }\n};\n\nconst getScaledDimensions = (width, height, maxWidth, maxHeight) => {\n if (width <= maxWidth && height <= maxHeight) {\n return {\n width: width % 2 === 0 ? width : width - 1,\n height: height % 2 === 0 ? height : height - 1\n };\n }\n const widthRatio = maxWidth / width;\n const heightRatio = maxHeight / height;\n const scale = Math.min(widthRatio, heightRatio);\n let scaledWidth = Math.round(width * scale);\n let scaledHeight = Math.round(height * scale);\n if (scaledWidth % 2 !== 0) {\n scaledWidth -= 1;\n }\n if (scaledHeight % 2 !== 0) {\n scaledHeight -= 1;\n }\n return {\n width: Math.min(scaledWidth, maxWidth),\n height: Math.min(scaledHeight, maxHeight)\n };\n};\nconst getObjectFitSize = (objectFit, elementSize, containerSize) => {\n const elementAspectRatio = elementSize.width / elementSize.height;\n const containerAspectRatio = containerSize.width / containerSize.height;\n switch (objectFit) {\n case \"contain\":\n if (elementAspectRatio > containerAspectRatio) {\n return {\n width: containerSize.width,\n height: containerSize.width / elementAspectRatio\n };\n } else {\n return {\n width: containerSize.height * elementAspectRatio,\n height: containerSize.height\n };\n }\n case \"cover\":\n if (elementAspectRatio > containerAspectRatio) {\n return {\n width: containerSize.height * elementAspectRatio,\n height: containerSize.height\n };\n } else {\n return {\n width: containerSize.width,\n height: containerSize.width / elementAspectRatio\n };\n }\n case \"fill\":\n return {\n width: containerSize.width,\n height: containerSize.height\n };\n default:\n return {\n width: elementSize.width,\n height: elementSize.height\n };\n }\n};\n\nconst blobUrlToFile = async (blobUrl, fileName) => {\n const response = await fetch(blobUrl);\n const blob = await response.blob();\n return new File([blob], fileName, { type: blob.type });\n};\nconst loadFile = (accept) => {\n return new Promise((resolve, reject) => {\n try {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = accept;\n input.style.display = \"none\";\n document.body.appendChild(input);\n const cleanup = () => {\n input.value = \"\";\n document.body.removeChild(input);\n };\n input.onchange = () => {\n const file = input.files && input.files[0];\n cleanup();\n if (!file) {\n reject(new Error(\"No file selected\"));\n return;\n }\n resolve(file);\n };\n input.click();\n } catch (error) {\n reject(error);\n }\n });\n};\nconst saveAsFile = (content, type, name) => {\n const blob = typeof content === \"string\" ? new Blob([content], { type }) : content;\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = name;\n a.click();\n URL.revokeObjectURL(url);\n};\nconst downloadFile = async (url, filename) => {\n try {\n const response = await fetch(url);\n const blob = await response.blob();\n const downloadUrl = window.URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = downloadUrl;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n window.URL.revokeObjectURL(downloadUrl);\n } catch (error) {\n throw error;\n }\n};\n\nconst detectMediaTypeFromUrl = async (url) => {\n try {\n const response = await fetch(url, { method: \"HEAD\" });\n const contentType = response.headers.get(\"Content-Type\");\n if (!contentType) return null;\n if (contentType.startsWith(\"image/\")) return \"image\";\n if (contentType.startsWith(\"video/\")) return \"video\";\n if (contentType.startsWith(\"audio/\")) return \"audio\";\n return null;\n } catch {\n return null;\n }\n};\n\nexport { VideoFrameExtractor, blobUrlToFile, detectMediaTypeFromUrl, downloadFile, extractAudio, getAudioDuration, getDefaultVideoFrameExtractor, getImageDimensions, getObjectFitSize, getScaledDimensions, getThumbnail, getThumbnailCached, getVideoMeta, hasAudio, limit, loadFile, saveAsFile, stitchAudio };\n//# sourceMappingURL=index.mjs.map\n","import { TrackElement, VideoElement } from \"@twick/timeline\";\nimport { useEffect, useState, useRef } from \"react\";\nimport { hasAudio } from \"@twick/media-utils\";\nimport { Loader2, VolumeX, Volume2, CheckCircle2, XCircle } from \"lucide-react\";\nimport { ICaptionGenerationPollingResponse } from \"../../types\";\n\nexport function GenerateCaptionsPanel({\n selectedElement,\n addCaptionsToTimeline,\n onGenerateCaptions,\n getCaptionstatus,\n pollingIntervalMs = 5000,\n}: {\n selectedElement: TrackElement;\n addCaptionsToTimeline: (captions: { s: number; e: number; t: string }[]) => void;\n onGenerateCaptions: (videoElement: VideoElement) => Promise<string | null>;\n getCaptionstatus: (reqId: string) => Promise<ICaptionGenerationPollingResponse>;\n pollingIntervalMs?: number;\n}) {\n const [containsAudio, setContainsAudio] = useState<boolean | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [isGenerating, setIsGenerating] = useState(false);\n const [pollingStatus, setPollingStatus] = useState<\"idle\" | \"polling\" | \"success\" | \"error\">(\"idle\");\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const pollingIntervalRef = useRef<NodeJS.Timeout | null>(null);\n const currentReqIdRef = useRef<string | null>(null);\n\n // Cleanup polling on unmount\n useEffect(() => {\n return () => {\n if (pollingIntervalRef.current) {\n clearInterval(pollingIntervalRef.current);\n }\n };\n }, []);\n\n const stopPolling = () => {\n if (pollingIntervalRef.current) {\n clearInterval(pollingIntervalRef.current);\n pollingIntervalRef.current = null;\n }\n };\n\n const startPolling = async (reqId: string) => {\n if (!getCaptionstatus) {\n return;\n }\n setPollingStatus(\"polling\");\n setIsGenerating(true);\n setErrorMessage(null);\n\n const poll = async () => {\n try {\n const response = await getCaptionstatus(reqId);\n\n \n if (response.status === \"completed\") {\n stopPolling();\n setPollingStatus(\"success\");\n setIsGenerating(false);\n \n // Add captions to timeline\n addCaptionsToTimeline(response.captions || []);\n \n // Reset status after 3 seconds\n setTimeout(() => {\n setPollingStatus(\"idle\");\n }, 3000);\n } else if (response.status === \"pending\") {\n // Continue polling - interval will call this again\n } else if (response.status === \"failed\") {\n stopPolling();\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(response.error || \"Failed to generate captions\");\n console.error(\"Error generating captions:\", response.error);\n }\n } catch (error) {\n stopPolling();\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(error instanceof Error ? error.message : \"Failed to get caption status\");\n console.error(\"Error polling for captions:\", error);\n }\n };\n\n // Poll immediately, then at configured interval (default 5 seconds)\n await poll();\n pollingIntervalRef.current = setInterval(poll, pollingIntervalMs);\n };\n\n const handleGenerateCaptions = async () => {\n if (!(selectedElement instanceof VideoElement)) {\n return;\n }\n\n setIsGenerating(true);\n setPollingStatus(\"polling\");\n const videoElement = selectedElement as VideoElement;\n \n\n try {\n const reqId = await onGenerateCaptions(videoElement);\n if (!reqId) {\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(\"Failed to start caption generation\");\n console.error(\"Error generating captions: Failed to start caption generation\");\n return;\n }\n currentReqIdRef.current = reqId;\n await startPolling(reqId);\n } catch (error) {\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(error instanceof Error ? error.message : \"Failed to start caption generation\");\n console.error(\"Error generating captions:\", error);\n }\n };\n\n const checkAudio = async () => {\n setIsLoading(true);\n if (selectedElement instanceof VideoElement) {\n const videoElement = selectedElement as VideoElement;\n const videoUrl = videoElement.getSrc();\n if (videoUrl) {\n try {\n const hasAudioTrack = await hasAudio(videoUrl);\n setContainsAudio(hasAudioTrack);\n } catch (error) {\n console.error(\"Error checking audio:\", error);\n setContainsAudio(false);\n }\n } else {\n setContainsAudio(false);\n }\n } else {\n setContainsAudio(false);\n }\n setIsLoading(false);\n };\n\n useEffect(() => {\n checkAudio();\n // Reset polling state when element changes\n stopPolling();\n setPollingStatus(\"idle\");\n setIsGenerating(false);\n setErrorMessage(null);\n }, [selectedElement]);\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Generate Captions Panel</div>\n \n {/* Loading State */}\n {isLoading && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Loader2 className=\"empty-state-icon animate-spin\" />\n <p className=\"empty-state-text\">Checking for audio...</p>\n </div>\n </div>\n </div>\n )}\n\n {/* No Audio State */}\n {!isLoading && containsAudio === false && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <VolumeX className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">No audio track found in this video</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Audio Present State */}\n {!isLoading && containsAudio === true && pollingStatus === \"idle\" && !isGenerating && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Volume2 className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">Audio detected! You can now generate captions</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Polling/Generating State */}\n {!isLoading && isGenerating && pollingStatus === \"polling\" && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Loader2 className=\"empty-state-icon animate-spin\" />\n <p className=\"empty-state-text\">Generating captions... Please wait</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Success State */}\n {!isLoading && pollingStatus === \"success\" && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <CheckCircle2 className=\"empty-state-icon\" color=\"var(--color-green-500)\" />\n <p className=\"empty-state-text\">Captions generated successfully!</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Error State */}\n {!isLoading && pollingStatus === \"error\" && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <XCircle className=\"empty-state-icon\" color=\"var(--color-red-500)\" />\n <p className=\"empty-state-text\">{errorMessage || \"Failed to generate captions\"}</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Generate Button */}\n {!isLoading && (\n <div className=\"flex panel-section\">\n <button\n onClick={handleGenerateCaptions}\n disabled={!containsAudio || isGenerating}\n className=\"btn-primary w-full\"\n >\n {isGenerating ? \"Generating...\" : \"Generate Captions\"}\n </button>\n </div>\n )}\n </div>\n );\n}\n","import { TextElement } from \"@twick/timeline\";\nimport type { PropertiesPanelProps } from \"../../types\";\nimport { AccordionItem } from \"../shared/accordion-item\";\nimport { PropertyRow } from \"./property-row\";\nimport { Type, AlignLeft, AlignCenter, AlignRight, Bold, Italic } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport function TextPropsPanel({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n if (!(selectedElement instanceof TextElement)) return null;\n\n const textProps = selectedElement.getProps() || {};\n\n const [isTypographyOpen, setIsTypographyOpen] = useState(false);\n\n const currentAlign = textProps.textAlign ?? \"center\";\n const currentWeight = textProps.fontWeight ?? 400;\n const isBold = currentWeight >= 600;\n const isItalic = textProps.fontStyle === \"italic\";\n\n const handleUpdate = (patch: Partial<typeof textProps>) => {\n if (!selectedElement) return;\n const next = { ...textProps, ...patch };\n selectedElement.setProps(next);\n updateElement?.(selectedElement);\n };\n\n const toggleBold = () => {\n handleUpdate({ fontWeight: isBold ? 400 : 700 });\n };\n\n const toggleItalic = () => {\n handleUpdate({ fontStyle: isItalic ? \"normal\" : \"italic\" });\n };\n\n const setAlign = (align: \"left\" | \"center\" | \"right\") => {\n handleUpdate({ textAlign: align });\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Typography</div>\n <AccordionItem\n title=\"Typography\"\n icon={<Type className=\"icon-sm\" />}\n isOpen={isTypographyOpen}\n onToggle={() => setIsTypographyOpen((open) => !open)}\n >\n <div className=\"properties-group\">\n {/* Font size */}\n <div className=\"property-section\">\n <PropertyRow\n label=\"Font size\"\n secondary={<span>{textProps.fontSize ?? 48}px</span>}\n >\n <input\n type=\"range\"\n min={8}\n max={160}\n value={textProps.fontSize ?? 48}\n onChange={(e) =>\n handleUpdate({ fontSize: Number(e.target.value) })\n }\n className=\"slider-purple\"\n />\n </PropertyRow>\n </div>\n\n {/* Style: bold / italic */}\n <div className=\"property-section\">\n <PropertyRow label=\"Style\">\n <button\n type=\"button\"\n className={`form-btn ${isBold ? \"active\" : \"\"}`}\n onClick={toggleBold}\n title=\"Bold\"\n >\n <Bold className=\"icon-sm\" />\n </button>\n <button\n type=\"button\"\n className={`form-btn ${isItalic ? \"active\" : \"\"}`}\n onClick={toggleItalic}\n title=\"Italic\"\n >\n <Italic className=\"icon-sm\" />\n </button>\n </PropertyRow>\n </div>\n\n {/* Alignment */}\n <div className=\"property-section\">\n <PropertyRow label=\"Align\">\n <button\n type=\"button\"\n className={`form-btn ${currentAlign === \"left\" ? \"active\" : \"\"}`}\n onClick={() => setAlign(\"left\")}\n title=\"Align left\"\n >\n <AlignLeft className=\"icon-sm\" />\n </button>\n <button\n type=\"button\"\n className={`form-btn ${\n currentAlign === \"center\" ? \"active\" : \"\"\n }`}\n onClick={() => setAlign(\"center\")}\n title=\"Align center\"\n >\n <AlignCenter className=\"icon-sm\" />\n </button>\n <button\n type=\"button\"\n className={`form-btn ${\n currentAlign === \"right\" ? \"active\" : \"\"\n }`}\n onClick={() => setAlign(\"right\")}\n title=\"Align right\"\n >\n <AlignRight className=\"icon-sm\" />\n </button>\n </PropertyRow>\n </div>\n\n </div>\n </AccordionItem>\n </div>\n );\n}\n\n","import { useEffect, useState } from \"react\";\nimport {\n ArrowElement,\n LineElement,\n RectElement,\n CircleElement,\n type TrackElement,\n} from \"@twick/timeline\";\nimport { Palette } from \"lucide-react\";\nimport { AccordionItem } from \"../shared/accordion-item\";\nimport type { PropertiesPanelProps } from \"../../types\";\n\n/** Parse fill to hex for color input; supports #hex and rgba(). */\nfunction fillToHex(fill: string | undefined): string {\n if (!fill) return \"#f59e0b\";\n if (fill.startsWith(\"#\")) return fill.slice(0, 7);\n const rgba = fill.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n if (rgba) {\n const r = Number(rgba[1]).toString(16).padStart(2, \"0\");\n const g = Number(rgba[2]).toString(16).padStart(2, \"0\");\n const b = Number(rgba[3]).toString(16).padStart(2, \"0\");\n return `#${r}${g}${b}`;\n }\n return \"#f59e0b\";\n}\n\ntype ShapeElement = ArrowElement | LineElement | RectElement | CircleElement;\n\nfunction isShapeElement(\n el: TrackElement | null | undefined\n): el is ShapeElement {\n return (\n el != null &&\n (el instanceof ArrowElement ||\n el instanceof LineElement ||\n el instanceof RectElement ||\n el instanceof CircleElement)\n );\n}\n\nexport function AnnotationStylePanel({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n const [styleOpen, setStyleOpen] = useState(true);\n const [fill, setFill] = useState(\"#f59e0b\");\n const [opacity, setOpacity] = useState(1);\n const [radius, setRadius] = useState<number | null>(null);\n const [thickness, setThickness] = useState<number | null>(null);\n\n const shape = isShapeElement(selectedElement) ? selectedElement : null;\n\n useEffect(() => {\n if (!shape) return;\n\n const props = shape.getProps();\n // Resolve fill\n const currentFill =\n props?.fill ??\n (shape instanceof RectElement || shape instanceof CircleElement\n ? shape.getFill()\n : undefined);\n setFill(fillToHex(currentFill));\n\n // Opacity\n setOpacity(shape.getOpacity() ?? 1);\n\n // Radius / thickness defaults by type\n if (shape instanceof RectElement) {\n setRadius(shape.getCornerRadius());\n setThickness(null);\n } else if (shape instanceof CircleElement) {\n setRadius(shape.getRadius());\n setThickness(null);\n } else if (shape instanceof LineElement) {\n setThickness(props?.height ?? 4);\n setRadius(props?.radius ?? 4);\n } else if (shape instanceof ArrowElement) {\n setRadius(props?.radius ?? 4);\n setThickness(null);\n }\n }, [shape, selectedElement?.getId()]);\n\n const handleFillChange = (value: string) => {\n if (!shape) return;\n setFill(value);\n const props = shape.getProps();\n\n if (shape instanceof RectElement || shape instanceof CircleElement) {\n shape.setFill(value);\n } else {\n shape.setProps({ ...props, fill: value });\n }\n\n updateElement?.(shape);\n };\n\n const handleOpacityChange = (value: number) => {\n if (!shape) return;\n setOpacity(value);\n shape.setOpacity(value);\n updateElement?.(shape);\n };\n\n const handleRadiusChange = (value: number) => {\n if (!shape) return;\n setRadius(value);\n if (shape instanceof RectElement) {\n shape.setCornerRadius(value);\n } else if (shape instanceof CircleElement) {\n shape.setRadius(value);\n } else {\n const props = shape.getProps();\n shape.setProps({ ...props, radius: value });\n }\n updateElement?.(shape);\n };\n\n const handleThicknessChange = (value: number) => {\n if (!shape || !(shape instanceof LineElement)) return;\n setThickness(value);\n const props = shape.getProps();\n shape.setProps({ ...props, height: value, lineWidth: value });\n updateElement?.(shape);\n };\n\n if (!shape) return null;\n\n return (\n <div className=\"panel-container\">\n <AccordionItem\n title=\"Shape style\"\n icon={<Palette className=\"icon-sm\" />}\n isOpen={styleOpen}\n onToggle={() => setStyleOpen((open) => !open)}\n >\n <div className=\"properties-group\">\n <div className=\"panel-section\">\n <label className=\"label-dark\">Color</label>\n <div className=\"color-control\">\n <label className=\"label-small\">Fill</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={fill}\n onChange={(e) => handleFillChange(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={fill}\n onChange={(e) => handleFillChange(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n </div>\n <div className=\"panel-section\">\n <label className=\"label-dark\">Opacity</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n step=\"1\"\n value={Math.round(opacity * 100)}\n onChange={(e) =>\n handleOpacityChange(Number(e.target.value) / 100)\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{Math.round(opacity * 100)}%</span>\n </div>\n </div>\n\n {/* Radius for box/circle/arrow/line (where applicable) */}\n {radius !== null && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">\n {shape instanceof CircleElement ? \"Radius (size)\" : \"Corner radius\"}\n </label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"200\"\n step=\"1\"\n value={radius}\n onChange={(e) => handleRadiusChange(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{Math.round(radius)}</span>\n </div>\n </div>\n )}\n\n {/* Thickness for line */}\n {thickness !== null && shape instanceof LineElement && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Thickness</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"1\"\n max=\"40\"\n step=\"1\"\n value={thickness}\n onChange={(e) =>\n handleThicknessChange(Number(e.target.value))\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">\n {Math.round(thickness)} px\n </span>\n </div>\n </div>\n )}\n </div>\n </AccordionItem>\n </div>\n );\n}\n","import { ElementProps } from \"../properties/element-props\";\nimport { TextEffects } from \"../properties/text-effects\";\nimport { Animation } from \"../properties/animation\";\nimport {\n VideoElement,\n TextElement,\n AudioElement,\n CaptionElement,\n ArrowElement,\n LineElement,\n RectElement,\n CircleElement,\n type TrackElement,\n Size,\n useTimelineContext,\n} from \"@twick/timeline\";\nimport { CaptionPropPanel } from \"../properties/caption-prop\";\nimport { PlaybackPropsPanel } from \"../properties/playback-props\";\nimport { GenerateCaptionsPanel } from \"../properties/generate-captions.tsx\";\nimport { TextPropsPanel } from \"../properties/text-props\";\nimport { AnnotationStylePanel } from \"../properties/annotation-style-panel\";\nimport { ICaptionGenerationPollingResponse, CaptionEntry } from \"../../types\";\nimport { useCallback } from \"react\";\n\nconst DEFAULT_CANVAS_BACKGROUND = \"#000000\";\n\ninterface PropertiesPanelContainerProps {\n selectedElement: TrackElement | null;\n updateElement: (element: TrackElement) => void;\n addCaptionsToTimeline: (captions: CaptionEntry[]) => void;\n onGenerateCaptions: (videoElement: VideoElement) => Promise<string | null>;\n getCaptionstatus: (reqId: string) => Promise<ICaptionGenerationPollingResponse>;\n pollingIntervalMs: number;\n videoResolution: Size;\n}\n\nexport function PropertiesPanelContainer({\n selectedElement,\n updateElement,\n addCaptionsToTimeline,\n onGenerateCaptions,\n getCaptionstatus,\n pollingIntervalMs,\n videoResolution,\n}: PropertiesPanelContainerProps) {\n const { editor, present } = useTimelineContext();\n const backgroundColor =\n present?.backgroundColor ??\n editor.getBackgroundColor() ??\n DEFAULT_CANVAS_BACKGROUND;\n\n const handleBackgroundColorChange = useCallback(\n (value: string) => {\n editor.setBackgroundColor(value);\n },\n [editor]\n );\n\n const annotationTitle =\n selectedElement instanceof ArrowElement\n ? \"Arrow callout\"\n : selectedElement instanceof LineElement\n ? \"Line\"\n : selectedElement instanceof RectElement\n ? \"Box\"\n : selectedElement instanceof CircleElement\n ? \"Circle\"\n : null;\n const title = annotationTitle\n ?? (selectedElement instanceof TextElement ? selectedElement.getText() : null)\n ?? selectedElement?.getName()\n ?? selectedElement?.getType()\n ?? \"Element\";\n\n return (\n <aside className=\"properties-panel\" aria-label=\"Element properties inspector\">\n <div className=\"properties-header\">\n {!selectedElement && (\n <h3 className=\"properties-title\">Composition</h3>\n )}\n {selectedElement && selectedElement.getType() === \"caption\" && (\n <h3 className=\"properties-title\">Caption</h3>\n )}\n {selectedElement && selectedElement.getType() !== \"caption\" && (\n <h3 className=\"properties-title\">\n {title}\n </h3>\n )}\n </div>\n\n <div className=\"prop-content\">\n {/* Composition inspector when nothing selected */}\n {!selectedElement && (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Canvas & Render</div>\n <div className=\"properties-group\">\n <div className=\"property-section\">\n <span className=\"property-label\">Size</span>\n <span className=\"properties-size-readonly\">\n {videoResolution.width} × {videoResolution.height}\n </span>\n </div>\n <div className=\"color-control\">\n <label className=\"label-small\">Background Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={backgroundColor}\n onChange={(e) =>\n handleBackgroundColorChange(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={backgroundColor}\n onChange={(e) =>\n handleBackgroundColorChange(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* Caption inspector when caption is selected */}\n {selectedElement instanceof CaptionElement && (\n <>\n <CaptionPropPanel\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n </>\n )}\n\n {/* Element inspector when non-caption is selected */}\n {selectedElement && !(selectedElement instanceof CaptionElement) && (\n <>\n {(() => {\n const isText = selectedElement instanceof TextElement;\n const isVideo = selectedElement instanceof VideoElement;\n const isAudio = selectedElement instanceof AudioElement;\n\n const isAnnotation =\n selectedElement instanceof ArrowElement ||\n selectedElement instanceof LineElement ||\n selectedElement instanceof RectElement ||\n selectedElement instanceof CircleElement;\n\n return (\n <>\n {/* Typography (Text only) */}\n {isText && (\n <TextPropsPanel\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Transform – visual elements only (not audio) */}\n {!isAudio && (\n <ElementProps\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Annotation style – color & opacity (arrow, highlight, blur) */}\n {isAnnotation && (\n <AnnotationStylePanel\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Playback + Volume – video and audio */}\n {(isVideo || isAudio) && (\n <PlaybackPropsPanel\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Text Effects – text only */}\n {isText && (\n <TextEffects\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Animations – visual elements only (not audio) */}\n {!isAudio && (\n <Animation\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Generate Captions – video only */}\n {isVideo && (\n <GenerateCaptionsPanel\n selectedElement={selectedElement}\n addCaptionsToTimeline={addCaptionsToTimeline}\n onGenerateCaptions={onGenerateCaptions}\n getCaptionstatus={getCaptionstatus}\n pollingIntervalMs={pollingIntervalMs}\n />\n )}\n </>\n );\n })()}\n </>\n )}\n </div>\n </aside>\n );\n}\n","import {\n PLAYER_STATE,\n ProjectJSON,\n exportChaptersAsJSON,\n exportChaptersAsYouTube,\n exportCaptionsAsSRT,\n exportCaptionsAsVTT,\n getCaptionLanguages,\n useTimelineContext,\n VideoElement,\n} from \"@twick/timeline\";\nimport { ICaptionGenerationPollingResponse, StudioConfig, CaptionEntry } from \"../types\";\nimport { loadFile, saveAsFile } from \"@twick/media-utils\";\nimport { useState } from \"react\";\nimport { useLivePlayerContext } from \"@twick/live-player\";\n\nconst useStudioOperation = (studioConfig?: StudioConfig) => {\n const { editor, present, videoResolution } = useTimelineContext();\n const { setSeekTime, setPlayerState } = useLivePlayerContext();\n const [projectName, setProjectName] = useState(\"\");\n\n const onNewProject = () => {\n setPlayerState(PLAYER_STATE.PAUSED);\n editor.loadProject({\n tracks: [],\n version: 0,\n });\n setSeekTime(0);\n }\n\n const onLoadProject = async () => {\n let project: ProjectJSON;\n setPlayerState(PLAYER_STATE.PAUSED);\n if (studioConfig?.loadProject) {\n project = await studioConfig.loadProject();\n } else {\n const file = await loadFile(\"application/json\");\n const text = await file.text();\n setProjectName(file.name);\n project = JSON.parse(text);\n }\n editor.loadProject(project);\n setSeekTime(0.01);\n };\n\n const onSaveProject = async () => {\n let fileName;\n if (projectName) {\n fileName = projectName;\n } else {\n fileName = prompt(\"Enter the name of the project\") || \"untitled-project\";\n fileName = fileName + \".json\";\n setProjectName(fileName);\n }\n if (studioConfig?.saveProject && present) {\n await studioConfig.saveProject(present, fileName);\n } else {\n const file = await saveAsFile(\n JSON.stringify(present),\n \"application/json\",\n fileName\n );\n if (file) {\n console.log(\"File saved\", file);\n }\n }\n };\n\n const onExportVideo = async () => {\n if (studioConfig?.exportVideo && present) {\n await studioConfig.exportVideo(present, {\n outFile: \"output.mp4\",\n fps: 30,\n resolution: {\n width: videoResolution.width,\n height: videoResolution.height,\n },\n });\n } else {\n alert(\"Export video not supported in demo mode\");\n }\n };\n\n const onExportCaptions = async (format: \"srt\" | \"vtt\") => {\n if (!present) return;\n const baseName = (projectName || \"captions\").replace(/\\.json$/i, \"\");\n const languages = getCaptionLanguages(present);\n\n if (languages.length <= 1) {\n const content =\n format === \"srt\"\n ? exportCaptionsAsSRT(present, languages[0])\n : exportCaptionsAsVTT(present, languages[0]);\n await saveAsFile(content, \"text/plain\", `${baseName}.${format}`);\n return;\n }\n\n for (const language of languages) {\n const content =\n format === \"srt\"\n ? exportCaptionsAsSRT(present, language)\n : exportCaptionsAsVTT(present, language);\n await saveAsFile(content, \"text/plain\", `${baseName}.${language}.${format}`);\n }\n };\n\n const onExportChapters = async (format: \"youtube\" | \"json\") => {\n if (!present) return;\n const content =\n format === \"youtube\"\n ? exportChaptersAsYouTube(present)\n : exportChaptersAsJSON(present);\n const fileName = `${(projectName || \"chapters\").replace(/\\.json$/i, \"\")}.${\n format === \"youtube\" ? \"txt\" : \"json\"\n }`;\n await saveAsFile(content, \"text/plain\", fileName);\n };\n\n\n\n /**\n * Generates captions using the new polling-based service\n * Returns a function that can be called to start the generation process\n */\n const onGenerateCaptions = async (videoElement: VideoElement) => {\n // Use new polling-based service if available\n if (studioConfig?.captionGenerationService) {\n const service = studioConfig.captionGenerationService;\n const reqId = await service.generateCaptions(videoElement, present as ProjectJSON);\n return reqId;\n }\n alert(\"Generate captions not supported in demo mode\");\n return null;\n };\n\n const addCaptionsToTimeline = (captions: CaptionEntry[]) => {\n const updatedProjectJSON = studioConfig?.captionGenerationService?.updateProjectWithCaptions(captions);\n if (updatedProjectJSON) {\n editor.loadProject(updatedProjectJSON);\n }\n }\n\n const getCaptionstatus = async (reqId: string) => {\n if (studioConfig?.captionGenerationService) {\n const service = studioConfig.captionGenerationService;\n return await service.getRequestStatus(reqId);\n }\n return {\n status: \"failed\",\n error: \"Caption generation service not found\",\n } as ICaptionGenerationPollingResponse;\n }\n\n return { \n onLoadProject, \n onSaveProject, \n onExportVideo, \n onNewProject,\n onExportCaptions,\n onExportChapters,\n onGenerateCaptions,\n addCaptionsToTimeline,\n getCaptionstatus,\n };\n};\n\nexport default useStudioOperation;\n","/**\n * TwickStudio Component\n *\n * The main studio component that provides a complete video editing interface.\n * Integrates all major components including canvas, toolbar, media library,\n * and properties panel into a cohesive editing environment.\n *\n * @component\n * @example\n * ```tsx\n * <LivePlayerProvider>\n * <TimelineProvider initialData={initialData} contextId=\"studio-demo\">\n * <TwickStudio />\n * </TimelineProvider>\n * </LivePlayerProvider>\n * ```\n */\n\nimport { Toolbar } from \"./toolbar\";\nimport StudioHeader from \"./header\";\nimport { useStudioManager } from \"../hooks/use-studio-manager\";\nimport ElementPanelContainer from \"./container/element-panel-container\";\nimport { useTimelineContext } from \"@twick/timeline\";\nimport { MediaProvider } from \"../context/media-context\";\nimport { PropertiesPanelContainer } from \"./container/properties-panel-container\";\nimport VideoEditor from \"@twick/video-editor\";\nimport { useMemo } from \"react\";\nimport { StudioConfig } from \"../types\";\nimport useStudioOperation from \"../hooks/use-studio-operation\";\nimport { useGenerateCaptions } from \"..\";\n\nexport function TwickStudio({ studioConfig }: { studioConfig?: StudioConfig }) {\n const {\n selectedTool,\n setSelectedTool,\n selectedElement,\n addElement,\n updateElement,\n } = useStudioManager();\n const { editor, present, videoResolution, setVideoResolution } =\n useTimelineContext();\n const {\n onNewProject,\n onLoadProject,\n onSaveProject,\n onExportVideo,\n onExportCaptions,\n onExportChapters,\n } = useStudioOperation(studioConfig);\n\n const {\n onGenerateCaptions,\n addCaptionsToTimeline,\n getCaptionstatus,\n pollingIntervalMs,\n } = useGenerateCaptions(studioConfig);\n\n const twickStudiConfig: StudioConfig = useMemo(\n () => ({\n canvasMode: true,\n ...(studioConfig || {}),\n videoProps: {\n ...(studioConfig?.videoProps || {}),\n width: videoResolution.width,\n height: videoResolution.height,\n backgroundColor:\n present?.backgroundColor ??\n editor.getBackgroundColor() ??\n studioConfig?.videoProps?.backgroundColor,\n },\n }),\n [videoResolution, studioConfig, present?.backgroundColor, editor]\n );\n\n return (\n <MediaProvider>\n <div className=\"studio-container\">\n {/* Header */}\n <StudioHeader\n setVideoResolution={setVideoResolution}\n onNewProject={onNewProject}\n onLoadProject={onLoadProject}\n onSaveProject={onSaveProject}\n onExportVideo={onExportVideo}\n onExportCaptions={onExportCaptions}\n onExportChapters={onExportChapters}\n />\n {/* Main Content */}\n <div className=\"studio-content\">\n {/* Left Toolbar */}\n <Toolbar\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n customTools={twickStudiConfig.customTools}\n hiddenTools={twickStudiConfig.hiddenTools}\n />\n\n {/* Left Panel (Element Library) */}\n <div className=\"studio-left-panel\">\n <ElementPanelContainer\n videoResolution={videoResolution}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n selectedElement={selectedElement}\n addElement={addElement}\n updateElement={updateElement}\n uploadConfig={twickStudiConfig.uploadConfig}\n studioConfig={twickStudiConfig}\n />\n </div>\n\n {/* Center - Canvas and Transport */}\n <main className=\"main-container\">\n <div className=\"canvas-wrapper\">\n <div\n className=\"canvas-container\"\n style={{\n maxWidth: twickStudiConfig.playerProps?.maxWidth ?? \"100%\",\n }}\n >\n <VideoEditor editorConfig={twickStudiConfig} />\n </div>\n </div>\n </main>\n\n {/* Right Panel (Inspector + Props Toolbar) */}\n <div className=\"studio-right-panel\">\n <PropertiesPanelContainer\n selectedElement={selectedElement}\n updateElement={updateElement}\n addCaptionsToTimeline={addCaptionsToTimeline}\n onGenerateCaptions={onGenerateCaptions}\n getCaptionstatus={getCaptionstatus}\n pollingIntervalMs={pollingIntervalMs}\n videoResolution={videoResolution}\n />\n </div>\n </div>\n </div>\n </MediaProvider>\n );\n}\n","import { ProjectJSON, useTimelineContext, VideoElement } from \"@twick/timeline\";\nimport {\n ICaptionGenerationPollingResponse,\n StudioConfig,\n CaptionEntry,\n} from \"../types\";\n\nconst useGenerateCaptions = (studioConfig?: StudioConfig) => {\n const { editor, present } = useTimelineContext();\n /**\n * Generates captions using the new polling-based service\n * Returns a function that can be called to start the generation process\n */\n const onGenerateCaptions = async (videoElement: VideoElement) => {\n // Use new polling-based service if available\n if (studioConfig?.captionGenerationService) {\n const service = studioConfig.captionGenerationService;\n const reqId = await service.generateCaptions(\n videoElement,\n present as ProjectJSON\n );\n return reqId;\n }\n alert(\"Generate captions not supported in demo mode\");\n return null;\n };\n\n const addCaptionsToTimeline = (captions: CaptionEntry[]) => {\n const updatedProjectJSON =\n studioConfig?.captionGenerationService?.updateProjectWithCaptions(\n captions\n );\n if (updatedProjectJSON) {\n editor.loadProject(updatedProjectJSON);\n }\n };\n\n const getCaptionstatus = async (reqId: string) => {\n if (studioConfig?.captionGenerationService) {\n const service = studioConfig.captionGenerationService;\n return await service.getRequestStatus(reqId);\n }\n return {\n status: \"failed\",\n error: \"Caption generation service not found\",\n } as ICaptionGenerationPollingResponse;\n };\n\n const pollingIntervalMs =\n studioConfig?.captionGenerationService?.pollingIntervalMs ?? 5000;\n\n return {\n onGenerateCaptions,\n addCaptionsToTimeline,\n getCaptionstatus,\n pollingIntervalMs,\n };\n};\n\nexport default useGenerateCaptions;\n","/**\n * CirclePanel Component\n *\n * A panel for creating and editing circle shapes in the studio. Provides controls\n * for adjusting radius, fill color, opacity, stroke color, and line width.\n *\n * @component\n * @param {Object} props\n * @param {number} props.radius - Circle radius in pixels\n * @param {string} props.fillColor - Fill color in hex format\n * @param {string} props.strokeColor - Stroke color in hex format\n * @param {number} props.lineWidth - Stroke width in pixels\n * @param {(radius: number) => void} props.setRadius - Update circle radius\n * @param {(color: string) => void} props.setFillColor - Update fill color\n * @param {(opacity: number) => void} props.setOpacity - Update opacity\n * @param {(color: string) => void} props.setStrokeColor - Update stroke color\n * @param {(width: number) => void} props.setLineWidth - Update line width\n * @param {() => void} props.handleApplyChanges - Apply circle element changes\n *\n * @example\n * ```tsx\n * <CirclePanel\n * radius={50}\n * fillColor=\"#ff0000\"\n * opacity={100}\n * strokeColor=\"#000000\"\n * lineWidth={2}\n * setRadius={setRadius}\n * setFillColor={setFill}\n * setOpacity={setOpacity}\n * setStrokeColor={setStroke}\n * setLineWidth={setWidth}\n * handleApplyChanges={applyChanges}\n * />\n * ```\n */\n\nimport type {\n CirclePanelState,\n CirclePanelActions,\n} from \"../../hooks/use-circle-panel\";\n\nexport type CirclePanelProps = CirclePanelState & CirclePanelActions;\n\nexport function CirclePanel({\n radius,\n fillColor,\n strokeColor,\n lineWidth,\n operation,\n setRadius,\n setFillColor,\n setStrokeColor,\n setLineWidth,\n handleApplyChanges,\n}: CirclePanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Circle</div>\n {/* Radius */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Radius</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"10\"\n max=\"300\"\n value={radius}\n onChange={(e) => setRadius(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{radius}px</span>\n </div>\n </div>\n\n {/* Fill Color */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Fill Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={fillColor}\n onChange={(e) => setFillColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={fillColor}\n onChange={(e) => setFillColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n\n {/* Stroke Color */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Stroke Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n {/* Line Width */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Line Width</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"20\"\n value={lineWidth}\n onChange={(e) => setLineWidth(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{lineWidth}px</span>\n </div>\n </div>\n\n {/* Operation button (only for creation, not edits) */}\n {operation !== \"Apply Changes\" && (\n <div className=\"flex panel-section\">\n <button onClick={handleApplyChanges} className=\"btn-primary w-full\">\n {operation}\n </button>\n </div>\n )}\n </div>\n );\n}\n","/**\n * RectPanel Component\n * \n * A panel for creating and editing rectangle shapes in the studio. Provides controls\n * for adjusting corner radius, fill color, opacity, stroke color, and line width.\n * \n * @component\n * @param {Object} props\n * @param {number} props.cornerRadius - Corner radius in pixels\n * @param {string} props.fillColor - Fill color in hex format\n * @param {string} props.strokeColor - Stroke color in hex format\n * @param {number} props.lineWidth - Stroke width in pixels\n * @param {(radius: number) => void} props.setCornerRadius - Update corner radius\n * @param {(color: string) => void} props.setFillColor - Update fill color\n * @param {(opacity: number) => void} props.setOpacity - Update opacity\n * @param {(color: string) => void} props.setStrokeColor - Update stroke color\n * @param {(width: number) => void} props.setLineWidth - Update line width\n * @param {() => void} props.handleApplyChanges - Apply rectangle element changes\n * \n * @example\n * ```tsx\n * <RectPanel\n * cornerRadius={10}\n * fillColor=\"#ff0000\"\n * opacity={100}\n * strokeColor=\"#000000\"\n * lineWidth={2}\n * setCornerRadius={setRadius}\n * setFillColor={setFill}\n * setOpacity={setOpacity}\n * setStrokeColor={setStroke}\n * setLineWidth={setWidth}\n * handleApplyChanges={applyChanges}\n * />\n * ```\n */\n\nimport type { RectPanelState, RectPanelActions } from \"../../hooks/use-rect-panel\";\n\nexport type RectPanelProps = RectPanelState & RectPanelActions;\n\nexport function RectPanel({\n cornerRadius,\n fillColor,\n strokeColor,\n lineWidth,\n operation,\n setCornerRadius,\n setFillColor,\n setStrokeColor,\n setLineWidth,\n handleApplyChanges,\n}: RectPanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Rectangle</div>\n {/* Corner Radius */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Corner Radius</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n value={cornerRadius}\n onChange={(e) => setCornerRadius(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{cornerRadius}px</span>\n </div>\n </div>\n\n {/* Fill Color */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Fill Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={fillColor}\n onChange={(e) => setFillColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={fillColor}\n onChange={(e) => setFillColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n {/* Stroke Color */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Stroke Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n {/* Line Width */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Line Width</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"20\"\n value={lineWidth}\n onChange={(e) => setLineWidth(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{lineWidth}px</span>\n </div>\n </div>\n\n {/* Operation button (only for creation, not edits) */}\n {operation !== \"Apply Changes\" && (\n <div className=\"flex panel-section\">\n <button\n onClick={handleApplyChanges}\n className=\"btn-primary w-full\"\n >\n {operation}\n </button>\n </div>\n )}\n </div>\n );\n}","import type { StudioConfig } from \"../types\";\nimport { DEFAULT_PROJECT_TEMPLATES } from \"../templates/default-templates\";\n\nconst sharedVideoProps = {\n width: 720,\n height: 1280,\n};\n\nexport const DEFAULT_STUDIO_CONFIG: StudioConfig = {\n videoProps: sharedVideoProps,\n templates: DEFAULT_PROJECT_TEMPLATES,\n};\n\nexport const EDU_STUDIO_CONFIG: StudioConfig = {\n ...DEFAULT_STUDIO_CONFIG,\n hiddenTools: [\"circle\", \"rect\", \"generate-media\"],\n templates: DEFAULT_PROJECT_TEMPLATES.filter(\n (template) => template.category === \"edu\" || template.category === \"blank\"\n ),\n};\n\nexport const DEMO_STUDIO_CONFIG: StudioConfig = {\n ...DEFAULT_STUDIO_CONFIG,\n hiddenTools: [\"circle\", \"rect\"],\n templates: DEFAULT_PROJECT_TEMPLATES.filter(\n (template) => template.category === \"demo\" || template.category === \"blank\"\n ),\n};\n\nexport const MARKETING_STUDIO_CONFIG: StudioConfig = {\n ...DEFAULT_STUDIO_CONFIG,\n hiddenTools: [],\n templates: DEFAULT_PROJECT_TEMPLATES,\n};\n","import type { ProjectJSON } from \"@twick/timeline\";\nimport {\n exportCaptionsAsSRT,\n exportCaptionsAsVTT,\n exportChaptersAsJSON,\n getCaptionLanguages,\n} from \"@twick/timeline\";\n\nexport interface ProjectBundleExport {\n project: ProjectJSON;\n metadata: ProjectJSON[\"metadata\"];\n chaptersJson: string;\n captions: Array<{\n language: string;\n srt: string;\n vtt: string;\n }>;\n video?: {\n url?: string;\n fileName?: string;\n };\n}\n\nexport interface ExportProjectBundleOptions {\n videoUrl?: string;\n outFile?: string;\n}\n\n/**\n * Creates a portable export bundle with project JSON, chapters, and captions.\n * This intentionally avoids zip dependencies; callers can zip externally.\n */\nexport function exportProjectBundle(\n project: ProjectJSON,\n options?: ExportProjectBundleOptions\n): ProjectBundleExport {\n const languages = getCaptionLanguages(project);\n const captions = (languages.length ? languages : [\"default\"]).map((language) => ({\n language,\n srt: exportCaptionsAsSRT(project, language),\n vtt: exportCaptionsAsVTT(project, language),\n }));\n\n return {\n project,\n metadata: project.metadata,\n chaptersJson: exportChaptersAsJSON(project),\n captions,\n video: {\n url: options?.videoUrl,\n fileName: options?.outFile,\n },\n };\n}\n"],"names":["forwardRef","createElement","__iconNode","Wand2","Icon","jsxs","jsx","useState","useEffect","orientation","useTimelineContext","useEditorManager","TrackElement","useRef","Track","useCallback","BrowserMediaManager","createContext","useContext","VideoElement","AudioElement","ImageElement","config","TIMELINE_DROP_MEDIA_TYPE","Fragment","useMemo","throttle","AVAILABLE_TEXT_FONTS","TextElement","TIMELINE_ELEMENT_TYPE","EffectElement","gl","computeCaptionGeometry","CAPTION_STYLE","CaptionElement","useLivePlayerContext","prompt","TRACK_TYPES","LineElement","ArrowElement","RectElement","CircleElement","_a","rotation","opacity","ElementTextEffect","TEXT_EFFECTS","SparklesIcon","ANIMATIONS","ElementAnimation","CAPTION_STYLE_OPTIONS","Loader2","CheckCircle2","XCircle","PLAYER_STATE","getCaptionLanguages","exportCaptionsAsSRT","exportCaptionsAsVTT","exportChaptersAsYouTube","exportChaptersAsJSON"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40]}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/shared/src/utils.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/defaultAttributes.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/Icon.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/createLucideIcon.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/align-center.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/align-left.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/align-right.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/bold.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-down.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-right.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/circle-check.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/circle-x.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/circle.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/clapperboard.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/download.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/file.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/image.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/italic.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/loader-circle.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/message-square.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/music-2.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/music.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/palette.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/pause.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/play.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/plus.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/rectangle-horizontal.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/rectangle-vertical.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/ruler.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/save.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/scissors.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/search.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/sparkles.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/square.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/trash-2.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/type.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/upload.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/video.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/volume-2.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/volume-x.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/wand-sparkles.js","../src/components/toolbar.tsx","../src/components/header.tsx","../src/hooks/use-studio-manager.tsx","../src/hooks/use-cloud-media-upload.ts","../src/components/shared/cloud-media-upload.tsx","../src/components/shared/media-manager.ts","../src/components/shared/url-input.tsx","../src/context/media-context.tsx","../src/hooks/use-media-panel.ts","../src/hooks/use-audio-preview.ts","../src/components/panel/audio-panel.tsx","../src/components/shared/search-input.tsx","../src/helpers/asset-library.ts","../src/components/container/audio-panel-container.tsx","../src/components/panel/image-panel.tsx","../src/components/container/image-panel-container.tsx","../src/hooks/use-video-preview.ts","../src/components/panel/video-panel.tsx","../src/components/container/video-panel-container.tsx","../src/components/panel/text-panel.tsx","../src/hooks/use-text-panel.ts","../src/components/container/text-panel-container.tsx","../src/components/panel/text-style-panel.tsx","../src/components/container/text-style-panel-container.tsx","../../effects/dist/catalog.js","../src/hooks/use-effect-panel.ts","../src/helpers/effect-preview-manager.ts","../src/components/panel/effect-style-panel.tsx","../src/components/container/effect-style-panel-container.tsx","../src/components/panel/captions-panel.tsx","../src/helpers/constant.ts","../src/hooks/use-captions-panel.ts","../src/components/container/captions-panel-container.tsx","../src/components/container/generate-media-panel-container.tsx","../src/templates/default-templates.ts","../src/components/panel/template-gallery-panel.tsx","../src/hooks/use-screen-recorder.ts","../src/components/panel/record-panel.tsx","../src/components/panel/annotations-panel.tsx","../src/components/panel/chapters-panel.tsx","../src/components/panel/script-panel.tsx","../src/components/container/element-panel-container.tsx","../src/components/properties/property-row.tsx","../src/components/shared/accordion-item.tsx","../src/components/properties/element-props.tsx","../src/components/properties/text-effects.tsx","../src/components/properties/animation.tsx","../src/components/properties/caption-prop.tsx","../src/helpers/volume-db.ts","../src/components/properties/playback-props.tsx","../../media-utils/dist/index.mjs","../src/components/properties/generate-captions.tsx","../src/components/properties/text-props.tsx","../src/components/properties/annotation-style-panel.tsx","../src/components/container/properties-panel-container.tsx","../src/hooks/use-studio-operation.ts","../src/components/twick-studio.tsx","../src/hooks/use-generate-captions.ts","../src/components/panel/circle-panel.tsx","../src/components/panel/rect-panel.tsx","../src/profiles/index.ts","../src/helpers/export-project-bundle.ts"],"sourcesContent":["/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n};\n\nexport { hasA11yProp, mergeClasses, toCamelCase, toKebabCase, toPascalCase };\n//# sourceMappingURL=utils.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { mergeClasses, hasA11yProp } from './shared/src/utils.js';\n\nconst Icon = forwardRef(\n ({\n color = \"currentColor\",\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = \"\",\n children,\n iconNode,\n ...rest\n }, ref) => createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,\n className: mergeClasses(\"lucide\", className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n )\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from './shared/src/utils.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M17 12H7\", key: \"16if0g\" }],\n [\"path\", { d: \"M19 18H5\", key: \"18s9l3\" }],\n [\"path\", { d: \"M21 6H3\", key: \"1jwq7v\" }]\n];\nconst AlignCenter = createLucideIcon(\"align-center\", __iconNode);\n\nexport { __iconNode, AlignCenter as default };\n//# sourceMappingURL=align-center.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 12H3\", key: \"6jk70r\" }],\n [\"path\", { d: \"M17 18H3\", key: \"1amg6g\" }],\n [\"path\", { d: \"M21 6H3\", key: \"1jwq7v\" }]\n];\nconst AlignLeft = createLucideIcon(\"align-left\", __iconNode);\n\nexport { __iconNode, AlignLeft as default };\n//# sourceMappingURL=align-left.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 12H9\", key: \"dn1m92\" }],\n [\"path\", { d: \"M21 18H7\", key: \"1ygte8\" }],\n [\"path\", { d: \"M21 6H3\", key: \"1jwq7v\" }]\n];\nconst AlignRight = createLucideIcon(\"align-right\", __iconNode);\n\nexport { __iconNode, AlignRight as default };\n//# sourceMappingURL=align-right.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n { d: \"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\", key: \"mg9rjx\" }\n ]\n];\nconst Bold = createLucideIcon(\"bold\", __iconNode);\n\nexport { __iconNode, Bold as default };\n//# sourceMappingURL=bold.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"m6 9 6 6 6-6\", key: \"qrunsl\" }]];\nconst ChevronDown = createLucideIcon(\"chevron-down\", __iconNode);\n\nexport { __iconNode, ChevronDown as default };\n//# sourceMappingURL=chevron-down.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"m9 18 6-6-6-6\", key: \"mthhwq\" }]];\nconst ChevronRight = createLucideIcon(\"chevron-right\", __iconNode);\n\nexport { __iconNode, ChevronRight as default };\n//# sourceMappingURL=chevron-right.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"m9 12 2 2 4-4\", key: \"dzmm74\" }]\n];\nconst CircleCheck = createLucideIcon(\"circle-check\", __iconNode);\n\nexport { __iconNode, CircleCheck as default };\n//# sourceMappingURL=circle-check.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"m15 9-6 6\", key: \"1uzhvr\" }],\n [\"path\", { d: \"m9 9 6 6\", key: \"z0biqf\" }]\n];\nconst CircleX = createLucideIcon(\"circle-x\", __iconNode);\n\nexport { __iconNode, CircleX as default };\n//# sourceMappingURL=circle-x.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }]];\nconst Circle = createLucideIcon(\"circle\", __iconNode);\n\nexport { __iconNode, Circle as default };\n//# sourceMappingURL=circle.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n { d: \"M20.2 6 3 11l-.9-2.4c-.3-1.1.3-2.2 1.3-2.5l13.5-4c1.1-.3 2.2.3 2.5 1.3Z\", key: \"1tn4o7\" }\n ],\n [\"path\", { d: \"m6.2 5.3 3.1 3.9\", key: \"iuk76l\" }],\n [\"path\", { d: \"m12.4 3.4 3.1 4\", key: \"6hsd6n\" }],\n [\"path\", { d: \"M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z\", key: \"ltgou9\" }]\n];\nconst Clapperboard = createLucideIcon(\"clapperboard\", __iconNode);\n\nexport { __iconNode, Clapperboard as default };\n//# sourceMappingURL=clapperboard.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 15V3\", key: \"m9g1x1\" }],\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }],\n [\"path\", { d: \"m7 10 5 5 5-5\", key: \"brsn70\" }]\n];\nconst Download = createLucideIcon(\"download\", __iconNode);\n\nexport { __iconNode, Download as default };\n//# sourceMappingURL=download.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }]\n];\nconst File = createLucideIcon(\"file\", __iconNode);\n\nexport { __iconNode, File as default };\n//# sourceMappingURL=file.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", ry: \"2\", key: \"1m3agn\" }],\n [\"circle\", { cx: \"9\", cy: \"9\", r: \"2\", key: \"af1f0g\" }],\n [\"path\", { d: \"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\", key: \"1xmnt7\" }]\n];\nconst Image = createLucideIcon(\"image\", __iconNode);\n\nexport { __iconNode, Image as default };\n//# sourceMappingURL=image.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"line\", { x1: \"19\", x2: \"10\", y1: \"4\", y2: \"4\", key: \"15jd3p\" }],\n [\"line\", { x1: \"14\", x2: \"5\", y1: \"20\", y2: \"20\", key: \"bu0au3\" }],\n [\"line\", { x1: \"15\", x2: \"9\", y1: \"4\", y2: \"20\", key: \"uljnxc\" }]\n];\nconst Italic = createLucideIcon(\"italic\", __iconNode);\n\nexport { __iconNode, Italic as default };\n//# sourceMappingURL=italic.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"M21 12a9 9 0 1 1-6.219-8.56\", key: \"13zald\" }]];\nconst LoaderCircle = createLucideIcon(\"loader-circle\", __iconNode);\n\nexport { __iconNode, LoaderCircle as default };\n//# sourceMappingURL=loader-circle.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\", key: \"1lielz\" }]\n];\nconst MessageSquare = createLucideIcon(\"message-square\", __iconNode);\n\nexport { __iconNode, MessageSquare as default };\n//# sourceMappingURL=message-square.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"8\", cy: \"18\", r: \"4\", key: \"1fc0mg\" }],\n [\"path\", { d: \"M12 18V2l7 4\", key: \"g04rme\" }]\n];\nconst Music2 = createLucideIcon(\"music-2\", __iconNode);\n\nexport { __iconNode, Music2 as default };\n//# sourceMappingURL=music-2.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M9 18V5l12-2v13\", key: \"1jmyc2\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"circle\", { cx: \"18\", cy: \"16\", r: \"3\", key: \"1hluhg\" }]\n];\nconst Music = createLucideIcon(\"music\", __iconNode);\n\nexport { __iconNode, Music as default };\n//# sourceMappingURL=music.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z\",\n key: \"e79jfc\"\n }\n ],\n [\"circle\", { cx: \"13.5\", cy: \"6.5\", r: \".5\", fill: \"currentColor\", key: \"1okk4w\" }],\n [\"circle\", { cx: \"17.5\", cy: \"10.5\", r: \".5\", fill: \"currentColor\", key: \"f64h9f\" }],\n [\"circle\", { cx: \"6.5\", cy: \"12.5\", r: \".5\", fill: \"currentColor\", key: \"qy21gx\" }],\n [\"circle\", { cx: \"8.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"fotxhn\" }]\n];\nconst Palette = createLucideIcon(\"palette\", __iconNode);\n\nexport { __iconNode, Palette as default };\n//# sourceMappingURL=palette.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"zuxfzm\" }],\n [\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"1okwgv\" }]\n];\nconst Pause = createLucideIcon(\"pause\", __iconNode);\n\nexport { __iconNode, Pause as default };\n//# sourceMappingURL=pause.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"polygon\", { points: \"6 3 20 12 6 21 6 3\", key: \"1oa8hb\" }]];\nconst Play = createLucideIcon(\"play\", __iconNode);\n\nexport { __iconNode, Play as default };\n//# sourceMappingURL=play.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }]\n];\nconst Plus = createLucideIcon(\"plus\", __iconNode);\n\nexport { __iconNode, Plus as default };\n//# sourceMappingURL=plus.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"20\", height: \"12\", x: \"2\", y: \"6\", rx: \"2\", key: \"9lu3g6\" }]\n];\nconst RectangleHorizontal = createLucideIcon(\"rectangle-horizontal\", __iconNode);\n\nexport { __iconNode, RectangleHorizontal as default };\n//# sourceMappingURL=rectangle-horizontal.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"12\", height: \"20\", x: \"6\", y: \"2\", rx: \"2\", key: \"1oxtiu\" }]\n];\nconst RectangleVertical = createLucideIcon(\"rectangle-vertical\", __iconNode);\n\nexport { __iconNode, RectangleVertical as default };\n//# sourceMappingURL=rectangle-vertical.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z\",\n key: \"icamh8\"\n }\n ],\n [\"path\", { d: \"m14.5 12.5 2-2\", key: \"inckbg\" }],\n [\"path\", { d: \"m11.5 9.5 2-2\", key: \"fmmyf7\" }],\n [\"path\", { d: \"m8.5 6.5 2-2\", key: \"vc6u1g\" }],\n [\"path\", { d: \"m17.5 15.5 2-2\", key: \"wo5hmg\" }]\n];\nconst Ruler = createLucideIcon(\"ruler\", __iconNode);\n\nexport { __iconNode, Ruler as default };\n//# sourceMappingURL=ruler.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z\",\n key: \"1c8476\"\n }\n ],\n [\"path\", { d: \"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\", key: \"1ydtos\" }],\n [\"path\", { d: \"M7 3v4a1 1 0 0 0 1 1h7\", key: \"t51u73\" }]\n];\nconst Save = createLucideIcon(\"save\", __iconNode);\n\nexport { __iconNode, Save as default };\n//# sourceMappingURL=save.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M8.12 8.12 12 12\", key: \"1alkpv\" }],\n [\"path\", { d: \"M20 4 8.12 15.88\", key: \"xgtan2\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"path\", { d: \"M14.8 14.8 20 20\", key: \"ptml3r\" }]\n];\nconst Scissors = createLucideIcon(\"scissors\", __iconNode);\n\nexport { __iconNode, Scissors as default };\n//# sourceMappingURL=scissors.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m21 21-4.34-4.34\", key: \"14j7rj\" }],\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }]\n];\nconst Search = createLucideIcon(\"search\", __iconNode);\n\nexport { __iconNode, Search as default };\n//# sourceMappingURL=search.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z\",\n key: \"4pj2yx\"\n }\n ],\n [\"path\", { d: \"M20 3v4\", key: \"1olli1\" }],\n [\"path\", { d: \"M22 5h-4\", key: \"1gvqau\" }],\n [\"path\", { d: \"M4 17v2\", key: \"vumght\" }],\n [\"path\", { d: \"M5 18H3\", key: \"zchphs\" }]\n];\nconst Sparkles = createLucideIcon(\"sparkles\", __iconNode);\n\nexport { __iconNode, Sparkles as default };\n//# sourceMappingURL=sparkles.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }]\n];\nconst Square = createLucideIcon(\"square\", __iconNode);\n\nexport { __iconNode, Square as default };\n//# sourceMappingURL=square.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\", key: \"4alrt4\" }],\n [\"path\", { d: \"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\", key: \"v07s0e\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"11\", y2: \"17\", key: \"1uufr5\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"11\", y2: \"17\", key: \"xtxkd\" }]\n];\nconst Trash2 = createLucideIcon(\"trash-2\", __iconNode);\n\nexport { __iconNode, Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 4v16\", key: \"1654pz\" }],\n [\"path\", { d: \"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2\", key: \"e0r10z\" }],\n [\"path\", { d: \"M9 20h6\", key: \"s66wpe\" }]\n];\nconst Type = createLucideIcon(\"type\", __iconNode);\n\nexport { __iconNode, Type as default };\n//# sourceMappingURL=type.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 3v12\", key: \"1x0j5s\" }],\n [\"path\", { d: \"m17 8-5-5-5 5\", key: \"7q97r8\" }],\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }]\n];\nconst Upload = createLucideIcon(\"upload\", __iconNode);\n\nexport { __iconNode, Upload as default };\n//# sourceMappingURL=upload.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\",\n key: \"ftymec\"\n }\n ],\n [\"rect\", { x: \"2\", y: \"6\", width: \"14\", height: \"12\", rx: \"2\", key: \"158x01\" }]\n];\nconst Video = createLucideIcon(\"video\", __iconNode);\n\nexport { __iconNode, Video as default };\n//# sourceMappingURL=video.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z\",\n key: \"uqj9uw\"\n }\n ],\n [\"path\", { d: \"M16 9a5 5 0 0 1 0 6\", key: \"1q6k2b\" }],\n [\"path\", { d: \"M19.364 18.364a9 9 0 0 0 0-12.728\", key: \"ijwkga\" }]\n];\nconst Volume2 = createLucideIcon(\"volume-2\", __iconNode);\n\nexport { __iconNode, Volume2 as default };\n//# sourceMappingURL=volume-2.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z\",\n key: \"uqj9uw\"\n }\n ],\n [\"line\", { x1: \"22\", x2: \"16\", y1: \"9\", y2: \"15\", key: \"1ewh16\" }],\n [\"line\", { x1: \"16\", x2: \"22\", y1: \"9\", y2: \"15\", key: \"5ykzw1\" }]\n];\nconst VolumeX = createLucideIcon(\"volume-x\", __iconNode);\n\nexport { __iconNode, VolumeX as default };\n//# sourceMappingURL=volume-x.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72\",\n key: \"ul74o6\"\n }\n ],\n [\"path\", { d: \"m14 7 3 3\", key: \"1r5n42\" }],\n [\"path\", { d: \"M5 6v4\", key: \"ilb8ba\" }],\n [\"path\", { d: \"M19 14v4\", key: \"blhpug\" }],\n [\"path\", { d: \"M10 2v2\", key: \"7u0qdc\" }],\n [\"path\", { d: \"M7 8H3\", key: \"zfb6yr\" }],\n [\"path\", { d: \"M21 16h-4\", key: \"1cnmox\" }],\n [\"path\", { d: \"M11 3H9\", key: \"1obp7u\" }]\n];\nconst WandSparkles = createLucideIcon(\"wand-sparkles\", __iconNode);\n\nexport { __iconNode, WandSparkles as default };\n//# sourceMappingURL=wand-sparkles.js.map\n","/**\n * Toolbar Component\n * \n * A vertical toolbar that provides quick access to different editing tools\n * and media types. Displays icons with labels and optional keyboard shortcuts.\n * \n * @component\n * @param {Object} props\n * @param {string} props.selectedTool - Currently selected tool ID\n * @param {(tool: string) => void} props.setSelectedTool - Callback to update selected tool\n * \n * @example\n * ```tsx\n * <Toolbar\n * selectedTool=\"text\"\n * setSelectedTool={(tool) => console.log(`Selected ${tool}`)}\n * />\n * ```\n */\n\nimport { \n Type, \n Upload, \n Video,\n Image, \n Music,\n Circle,\n MessageSquare,\n Plus,\n Square,\n Wand2,\n File,\n} from 'lucide-react'\nimport type { ToolCategory } from '../types'\n\nconst defaultToolCategories: ToolCategory[] = [\n // { id: 'templates', name: 'Templates', icon: 'Plus', description: 'Start from a project template' },\n // { id: 'record', name: 'Record', icon: 'Upload', description: 'Record screen and import clip' },\n { id: 'video', name: 'Video', icon: 'Video', description: 'Add a video element' },\n { id: 'image', name: 'Image', icon: 'Image', description: 'Add an image element' },\n { id: 'audio', name: 'Audio', icon: 'Audio', description: 'Add an audio element' },\n { id: 'text', name: 'Text', icon: 'Type', description: 'Add text elements' },\n { id: 'text-style', name: 'Text Style', icon: 'Type', description: 'Apply text style presets' },\n { id: 'effect', name: 'Effect', icon: 'Wand2', description: 'Apply GL video effects' },\n { id: 'shape', name: 'Shape', icon: 'Square', description: 'Add lines, arrows, boxes, and circles' },\n // { id: 'chapters', name: 'Chapters', icon: 'File', description: 'Manage chapter markers' },\n // { id: 'script', name: 'Script', icon: 'Type', description: 'Build timeline from a script outline' },\n { id: 'caption', name: 'Caption', icon: 'MessageSquare', description: 'Manage captions'},\n { id: 'generate-media', name: 'Generate', icon: 'Wand2', description: 'Generate image or video with AI'},\n]\n\nconst getIcon = (iconName: string) => {\n switch (iconName) {\n case 'Plus': return Plus\n case 'Type': return Type\n case 'Upload': return Upload\n case 'Square': return Square\n case 'Image': return Image\n case 'Video': return Video\n case 'Audio': return Music\n case 'Circle': return Circle\n case 'Rect': return Square\n case 'MessageSquare': return MessageSquare\n case 'Wand2': return Wand2\n case 'File': return File\n default: return Plus\n }\n}\n\nexport function Toolbar({\n selectedTool,\n setSelectedTool,\n customTools = [],\n hiddenTools = [],\n}: {\n selectedTool: string;\n setSelectedTool: (tool: string) => void;\n customTools?: ToolCategory[];\n hiddenTools?: string[];\n}) {\n\n const mergedTools = [...defaultToolCategories, ...customTools].filter(\n (tool) => !hiddenTools.includes(tool.id)\n );\n const handleToolSelect = (toolId: string) => {\n setSelectedTool(toolId)\n }\n\n return (\n <div className=\"sidebar\">\n {/* Main Tools */}\n {mergedTools.map((tool) => {\n const Icon = getIcon(tool.icon)\n const isSelected = selectedTool === tool.id\n \n const tooltipText = `${tool.name}${tool.shortcut ? ` (${tool.shortcut})` : ''}`;\n return (\n <div\n key={tool.id}\n onClick={() => handleToolSelect(tool.id)}\n className={`toolbar-btn ${isSelected ? 'active' : ''}`}\n title={tooltipText}\n data-tooltip={tooltipText}\n >\n <Icon className=\"icon-sm\" />\n <span className=\"toolbar-label\">\n {tool.name}\n </span>\n </div>\n )\n })}\n </div>\n )\n}\n","/**\n * StudioHeader Component\n *\n * The top header bar of the studio interface. Contains the studio logo,\n * orientation controls, and action divs for saving and exporting.\n *\n * @component\n * @param {Object} props\n * @param {(resolution: Size) => void} props.setVideoResolution - Callback to update canvas resolution\n *\n * @example\n * ```tsx\n * <StudioHeader\n * setVideoResolution={(size) => console.log(`New size: ${size.width}x${size.height}`)}\n * />\n * ```\n */\n\nimport type { Size } from \"@twick/timeline\";\nimport { Save, Download, Clapperboard, File, Plus, RectangleVertical, RectangleHorizontal } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\n\ninterface StudioHeaderProps {\n setVideoResolution: (resolution: Size) => void;\n onNewProject: () => void;\n onLoadProject: () => void;\n onSaveProject: () => void;\n onExportVideo: () => void;\n onExportCaptions: (format: \"srt\" | \"vtt\") => void;\n onExportChapters: (format: \"youtube\" | \"json\") => void;\n}\nexport const StudioHeader = ({\n setVideoResolution,\n onNewProject,\n onLoadProject,\n onSaveProject,\n onExportVideo,\n}: StudioHeaderProps) => {\n const [orientation, setOrientation] = useState<\"horizontal\" | \"vertical\">(\n \"vertical\"\n );\n\n useEffect(() => {\n const orientation = localStorage.getItem(\"orientation\");\n if (orientation) {\n setOrientation(orientation as \"horizontal\" | \"vertical\");\n }\n }, []);\n\n const handleOrientationChange = (nextOrientation: \"horizontal\" | \"vertical\") => {\n if (nextOrientation === orientation) return;\n\n const confirmMessage =\n \"Changing orientation will create a new project with the new resolution. Do you want to continue?\";\n\n if (!window.confirm(confirmMessage)) {\n return;\n }\n\n // Create a fresh project for the new resolution\n onNewProject();\n setOrientation(nextOrientation);\n };\n\n useEffect(() => {\n if (orientation === \"horizontal\") {\n localStorage.setItem(\"orientation\", \"horizontal\");\n setVideoResolution({ width: 1280, height: 720 });\n } else {\n localStorage.setItem(\"orientation\", \"vertical\");\n setVideoResolution({ width: 720, height: 1280 });\n }\n }, [orientation]);\n\n return (\n <header className=\"header\">\n <div className=\"flex-container\">\n <Clapperboard className=\"icon-lg accent-purple\" />\n <h1 className=\"text-gradient\">\n Twick Studio\n </h1>\n <div className=\"header-separator\"></div>\n <div className=\"flex-container\" style={{ gap: \"0.5rem\" }}>\n <span className=\"text-sm opacity-80\">Orientation</span>\n <button\n className={`btn-ghost ${orientation === \"vertical\" ? \"btn-primary\" : \"\"}`}\n title=\"Portrait (720×1280)\"\n onClick={() => handleOrientationChange(\"vertical\")}\n >\n <RectangleVertical className=\"icon-sm\" />\n\n </button>\n <button\n className={`btn-ghost ${orientation === \"horizontal\" ? \"btn-primary\" : \"\"}`}\n title=\"Landscape (1280×720)\"\n onClick={() => handleOrientationChange(\"horizontal\")}\n >\n <RectangleHorizontal className=\"icon-sm\" />\n\n </button>\n </div>\n </div>\n <div className=\"flex-container\">\n <button\n className=\"btn-ghost\"\n title=\"New Project\"\n onClick={onNewProject}\n >\n <Plus className=\"icon-sm\" />\n New Project\n </button>\n <button\n className=\"btn-ghost\"\n title=\"Load Project\"\n onClick={onLoadProject}\n >\n <File className=\"icon-sm\" />\n Load Project\n </button>\n <button\n className=\"btn-ghost\"\n title=\"Save Draft\"\n onClick={onSaveProject}\n >\n <Save className=\"icon-sm\" />\n Save Draft\n </button>\n {/* <button\n className=\"btn-ghost\"\n title=\"Export captions as SRT\"\n onClick={() => onExportCaptions(\"srt\")}\n >\n <Download className=\"icon-sm\" />\n SRT\n </button>\n <button\n className=\"btn-ghost\"\n title=\"Export captions as VTT\"\n onClick={() => onExportCaptions(\"vtt\")}\n >\n <Download className=\"icon-sm\" />\n VTT\n </button>\n <button\n className=\"btn-ghost\"\n title=\"Export chapters as YouTube timestamps\"\n onClick={() => onExportChapters(\"youtube\")}\n >\n <Download className=\"icon-sm\" />\n Chapters TXT\n </button>\n <button\n className=\"btn-ghost\"\n title=\"Export chapters as JSON\"\n onClick={() => onExportChapters(\"json\")}\n >\n <Download className=\"icon-sm\" />\n Chapters JSON\n </button> */}\n <button\n className=\"btn-primary\"\n title=\"Export\"\n onClick={onExportVideo}\n >\n <Download className=\"icon-sm\" />\n Export\n </button>\n </div>\n </header>\n );\n};\n\nexport default StudioHeader;\n","/**\n * useStudioManager Hook\n *\n * A custom hook that manages the studio's state and operations.\n * Handles tool selection, element management, and timeline interactions.\n *\n * @returns {Object} Studio manager methods and state\n * @property {string} selectedTool - Currently selected tool ID\n * @property {(tool: string) => void} setSelectedTool - Update selected tool\n * @property {TrackElement | null} selectedElement - Currently selected timeline element\n * @property {(element: TrackElement) => void} addElement - Add element to timeline\n * @property {(element: TrackElement) => void} updateElement - Update existing element\n *\n * @example\n * ```tsx\n * const {\n * selectedTool,\n * setSelectedTool,\n * selectedElement,\n * addElement,\n * updateElement\n * } = useStudioManager();\n * ```\n */\n\nimport { Track, TrackElement, useTimelineContext } from \"@twick/timeline\";\nimport { useEditorManager } from \"@twick/video-editor\";\nimport { useEffect, useRef, useState } from \"react\";\n\nconst SHAPES_TOOLS = [\"rect\", \"circle\", \"line\", \"arrow\"] as string[];\n\nexport const useStudioManager = () => {\n const [selectedProp, setSelectedProp] = useState(\"element-props\");\n\n const { selectedItem } = useTimelineContext();\n\n const { addElement, updateElement } = useEditorManager();\n\n const selectedElement =\n selectedItem instanceof TrackElement ? selectedItem : null;\n\n const [selectedTool, setSelectedTool] = useState<string>(\"none\");\n\n const isToolChanged = useRef(false);\n\n useEffect(() => {\n if (selectedItem instanceof TrackElement) {\n const elementType = selectedItem.getType();\n if(SHAPES_TOOLS.includes(elementType)) {\n setSelectedTool(\"shape\");\n } else {\n setSelectedTool(selectedItem.getType());\n }\n isToolChanged.current = true;\n } else if (selectedItem instanceof Track) {\n // do-nothing\n } else {\n setSelectedTool(\"video\");\n }\n }, [selectedItem]);\n\n return {\n selectedProp,\n setSelectedProp,\n selectedTool,\n setSelectedTool,\n selectedElement,\n addElement,\n updateElement,\n };\n};\n","import { useCallback, useState } from \"react\";\n\nexport type CloudUploadProvider = \"s3\" | \"gcs\";\n\nexport interface UseCloudMediaUploadConfig {\n uploadApiUrl: string;\n provider: CloudUploadProvider;\n}\n\n/** Response from S3 presign API (e.g. file-uploader Lambda). */\nexport interface S3PresignResponse {\n uploadUrl: string;\n key?: string;\n bucket?: string;\n contentType?: string;\n expiresIn?: number;\n}\n\n/** Response from GCS upload API (server-side upload). */\nexport interface GCSUploadResponse {\n url: string;\n}\n\nexport interface UseCloudMediaUploadReturn {\n uploadFile: (file: File) => Promise<{ url: string }>;\n isUploading: boolean;\n progress: number;\n error: string | null;\n resetError: () => void;\n}\n\nconst putFileWithProgress = (\n uploadUrl: string,\n file: File,\n onProgress: (percent: number) => void\n): Promise<void> => {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable) {\n onProgress((e.loaded / e.total) * 100);\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n onProgress(100);\n resolve();\n } else {\n reject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => reject(new Error(\"Upload failed\")));\n xhr.addEventListener(\"abort\", () => reject(new Error(\"Upload aborted\")));\n\n xhr.open(\"PUT\", uploadUrl);\n xhr.setRequestHeader(\"Content-Type\", file.type || \"application/octet-stream\");\n xhr.send(file);\n });\n};\n\nexport const useCloudMediaUpload = (\n config: UseCloudMediaUploadConfig\n): UseCloudMediaUploadReturn => {\n const { uploadApiUrl, provider } = config;\n const [isUploading, setIsUploading] = useState(false);\n const [progress, setProgress] = useState(0);\n const [error, setError] = useState<string | null>(null);\n\n const resetError = useCallback(() => {\n setError(null);\n }, []);\n\n const uploadFile = useCallback(\n async (file: File): Promise<{ url: string }> => {\n setIsUploading(true);\n setProgress(0);\n setError(null);\n\n try {\n if (provider === \"s3\") {\n const presignRes = await fetch(uploadApiUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n filename: file.name,\n contentType: file.type || \"application/octet-stream\",\n }),\n });\n\n if (!presignRes.ok) {\n const errBody = await presignRes.json().catch(() => ({}));\n throw new Error(\n (errBody as { error?: string }).error ??\n `Failed to get upload URL: ${presignRes.statusText}`\n );\n }\n\n const presignData = (await presignRes.json()) as S3PresignResponse;\n const uploadUrl = presignData.uploadUrl;\n\n await putFileWithProgress(uploadUrl, file, setProgress);\n\n const publicUrl = uploadUrl.split(\"?\")[0];\n return { url: publicUrl };\n }\n\n if (provider === \"gcs\") {\n setProgress(10);\n const formData = new FormData();\n formData.append(\"file\", file);\n\n const uploadRes = await fetch(uploadApiUrl, {\n method: \"POST\",\n body: formData,\n });\n\n if (!uploadRes.ok) {\n const errBody = await uploadRes.json().catch(() => ({}));\n throw new Error(\n (errBody as { error?: string }).error ??\n `Upload failed: ${uploadRes.statusText}`\n );\n }\n\n setProgress(100);\n const data = (await uploadRes.json()) as GCSUploadResponse;\n if (!data.url) {\n throw new Error(\"Upload response missing url\");\n }\n return { url: data.url };\n }\n\n throw new Error(`Unknown provider: ${provider}`);\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Upload failed\";\n setError(message);\n throw err;\n } finally {\n setIsUploading(false);\n setProgress(0);\n }\n },\n [uploadApiUrl, provider]\n );\n\n return {\n uploadFile,\n isUploading,\n progress,\n error,\n resetError,\n };\n};\n","import { useRef } from \"react\";\nimport { Upload } from \"lucide-react\";\nimport {\n useCloudMediaUpload,\n type CloudUploadProvider,\n} from \"../../hooks/use-cloud-media-upload\";\n\nexport interface CloudMediaUploadProps {\n onSuccess: (url: string, file: File) => void;\n onError?: (error: string) => void;\n accept?: string;\n uploadApiUrl: string;\n provider: CloudUploadProvider;\n buttonText?: string;\n className?: string;\n disabled?: boolean;\n id?: string;\n icon?: React.ReactNode;\n}\n\nexport const CloudMediaUpload = ({\n onSuccess,\n onError,\n accept,\n uploadApiUrl,\n provider,\n buttonText = \"Upload to cloud\",\n className,\n disabled = false,\n id: providedId,\n icon,\n}: CloudMediaUploadProps) => {\n const id = providedId ?? `cloud-media-upload-${Math.random().toString(36).slice(2, 9)}`;\n const inputRef = useRef<HTMLInputElement>(null);\n\n const {\n uploadFile,\n isUploading,\n progress,\n error,\n resetError,\n } = useCloudMediaUpload({ uploadApiUrl, provider });\n\n const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n\n try {\n const { url } = await uploadFile(file);\n onSuccess(url, file);\n if (inputRef.current) {\n inputRef.current.value = \"\";\n }\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Upload failed\";\n onError?.(message);\n }\n };\n\n const handleLabelClick = () => {\n if (disabled || isUploading) return;\n resetError();\n };\n\n return (\n <div className=\"file-input-container cloud-media-upload-container\">\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n className=\"file-input-hidden\"\n id={id}\n onChange={handleFileChange}\n disabled={disabled || isUploading}\n aria-label={buttonText}\n />\n <label\n htmlFor={id}\n className={className ?? \"btn-primary file-input-label\"}\n onClick={handleLabelClick}\n style={{ pointerEvents: disabled || isUploading ? \"none\" : undefined }}\n >\n {icon ?? <Upload className=\"icon-sm\" />}\n {isUploading ? `${Math.round(progress)}%` : buttonText}\n </label>\n {isUploading && (\n <div className=\"cloud-media-upload-progress\" role=\"progressbar\" aria-valuenow={progress} aria-valuemin={0} aria-valuemax={100}>\n <div\n className=\"cloud-media-upload-progress-fill\"\n style={{ width: `${progress}%` }}\n />\n </div>\n )}\n {error && (\n <div className=\"cloud-media-upload-error\" role=\"alert\">\n {error}\n </div>\n )}\n </div>\n );\n};\n","import { BrowserMediaManager } from \"@twick/video-editor\";\nimport type { MediaItem } from \"@twick/video-editor\";\n\nclass MediaManagerSingleton {\n private static instance: BrowserMediaManager | null = null;\n private static initializationPromise: Promise<void> | null = null;\n private static isInitialized = false;\n\n private constructor() {}\n\n public static getInstance(): BrowserMediaManager {\n if (!MediaManagerSingleton.instance) {\n MediaManagerSingleton.instance = new BrowserMediaManager();\n }\n return MediaManagerSingleton.instance;\n }\n\n public static async initializeDefaults(): Promise<void> {\n // If already initialized, return immediately\n if (MediaManagerSingleton.isInitialized) {\n return;\n }\n\n // If initialization is in progress, wait for it to complete\n if (MediaManagerSingleton.initializationPromise) {\n await MediaManagerSingleton.initializationPromise;\n return;\n }\n\n // Create and store the promise immediately to prevent concurrent initialization\n // This must be synchronous to prevent race conditions\n let resolvePromise: () => void;\n let rejectPromise: (error: any) => void;\n \n MediaManagerSingleton.initializationPromise = new Promise<void>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n });\n\n // Start initialization asynchronously\n (async () => {\n try {\n await MediaManagerSingleton.doInitializeDefaults();\n MediaManagerSingleton.isInitialized = true;\n resolvePromise!();\n } catch (error) {\n MediaManagerSingleton.initializationPromise = null;\n rejectPromise!(error);\n }\n })();\n \n return MediaManagerSingleton.initializationPromise;\n }\n\n private static async doInitializeDefaults(): Promise<void> {\n const manager = MediaManagerSingleton.getInstance();\n \n // Default video URLs\n const defaultVideos = [\n {\n name: \"Mountain Road\",\n url: \"https://videos.pexels.com/video-files/31708803/13510402_1080_1920_30fps.mp4\",\n type: \"video\",\n metadata: {\n name: \"Mountain Road\",\n source: \"pexels\",\n },\n },\n {\n name: \"Vase\",\n url: \"https://videos.pexels.com/video-files/4622990/4622990-uhd_1440_2560_30fps.mp4\",\n type: \"video\",\n metadata: {\n name: \"Vase\",\n source: \"pexels\",\n },\n },\n ] as Omit<MediaItem, \"id\">[];\n\n // Default image URLs\n const defaultImages = [\n {\n name: \"Mountain Road\",\n url: \"https://images.pexels.com/photos/1955134/pexels-photo-1955134.jpeg\",\n type: \"image\",\n metadata: {\n name: \"Mountain Road\",\n source: \"pexels\",\n },\n },\n {\n name: \"Waterfall\",\n url: \"https://images.pexels.com/photos/358457/pexels-photo-358457.jpeg\",\n type: \"image\",\n metadata: {\n name: \"Waterfall\",\n source: \"pexels\",\n },\n },\n ] as Omit<MediaItem, \"id\">[];\n\n // Default audio URLs\n const defaultAudios = [\n {\n name: \"Audio 1\",\n url: \"https://cdn.pixabay.com/audio/2022/03/14/audio_782eeb590e.mp3\",\n type: \"audio\",\n metadata: {\n name: \"Audio 1\",\n source: \"pixabay\",\n },\n },\n {\n name: \"Audio 2\",\n url: \"https://cdn.pixabay.com/audio/2025/01/24/audio_24048c78b6.mp3\",\n type: \"audio\",\n metadata: {\n name: \"Audio 2\",\n source: \"pixabay\",\n },\n },\n ] as Omit<MediaItem, \"id\">[];\n\n try {\n // Check if default videos already exist in the database\n const existingVideos = await manager.search({\n type: \"video\",\n query: \"\",\n });\n\n // Check if we already have the default videos by URL\n const existingVideoUrls = new Set(existingVideos.map((v) => v.url));\n const videosToAdd = defaultVideos.filter(\n (video) => !existingVideoUrls.has(video.url)\n );\n\n // Add default videos if they don't exist (check again right before adding to prevent race conditions)\n if (videosToAdd.length > 0) {\n // Double-check to prevent duplicates in case of race conditions\n const finalCheck = await manager.search({\n type: \"video\",\n query: \"\",\n });\n const finalVideoUrls = new Set(finalCheck.map((v) => v.url));\n const finalVideosToAdd = videosToAdd.filter(\n (video) => !finalVideoUrls.has(video.url)\n );\n \n if (finalVideosToAdd.length > 0) {\n await manager.addItems(finalVideosToAdd);\n }\n }\n\n // Check if default images already exist in the database\n const existingImages = await manager.search({\n type: \"image\",\n query: \"\",\n });\n\n // Check if we already have the default images by URL\n const existingImageUrls = new Set(existingImages.map((img) => img.url));\n const imagesToAdd = defaultImages.filter(\n (image) => !existingImageUrls.has(image.url)\n );\n\n // Add default images if they don't exist (check again right before adding)\n if (imagesToAdd.length > 0) {\n // Double-check to prevent duplicates in case of race conditions\n const finalCheck = await manager.search({\n type: \"image\",\n query: \"\",\n });\n const finalImageUrls = new Set(finalCheck.map((img) => img.url));\n const finalImagesToAdd = imagesToAdd.filter(\n (image) => !finalImageUrls.has(image.url)\n );\n \n if (finalImagesToAdd.length > 0) {\n await manager.addItems(finalImagesToAdd);\n }\n }\n\n // Check if default audio files already exist in the database\n const existingAudios = await manager.search({\n type: \"audio\",\n query: \"\",\n });\n\n // Check if we already have the default audio files by URL\n const existingAudioUrls = new Set(existingAudios.map((a) => a.url));\n const audiosToAdd = defaultAudios.filter(\n (audio) => !existingAudioUrls.has(audio.url)\n );\n\n // Add default audio files if they don't exist (check again right before adding)\n if (audiosToAdd.length > 0) {\n // Double-check to prevent duplicates in case of race conditions\n const finalCheck = await manager.search({\n type: \"audio\",\n query: \"\",\n });\n const finalAudioUrls = new Set(finalCheck.map((a) => a.url));\n const finalAudiosToAdd = audiosToAdd.filter(\n (audio) => !finalAudioUrls.has(audio.url)\n );\n \n if (finalAudiosToAdd.length > 0) {\n await manager.addItems(finalAudiosToAdd);\n }\n }\n } catch (error) {\n // Error is handled in initializeDefaults, just re-throw it\n throw error;\n }\n }\n}\n\n// Export a function to get the singleton instance\nexport const getMediaManager = () => MediaManagerSingleton.getInstance();\n\n// Export a function to initialize default videos\nexport const initializeDefaultVideos = () => MediaManagerSingleton.initializeDefaults(); ","import { useState } from \"react\";\nimport { Plus } from \"lucide-react\";\n\ntype MediaType = \"video\" | \"audio\" | \"image\";\n\nconst EXTENSIONS: Record<MediaType, string[]> = {\n video: [\"mp4\", \"webm\", \"ogg\", \"mov\", \"mkv\", \"m3u8\"],\n audio: [\"mp3\", \"wav\", \"ogg\", \"m4a\", \"aac\", \"flac\"],\n image: [\"jpg\", \"jpeg\", \"png\", \"gif\", \"webp\", \"svg\"],\n};\n\nfunction isValidUrl(url: string) {\n try {\n // eslint-disable-next-line no-new\n new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction matchesType(url: string, type: MediaType) {\n const pathname = (() => {\n try {\n return new URL(url).pathname.toLowerCase();\n } catch {\n return url.toLowerCase();\n }\n })();\n const ext = pathname.split(\".\").pop() || \"\";\n return EXTENSIONS[type].includes(ext);\n}\n\n// (name extraction removed; naming handled by caller if needed)\n\nexport default function UrlInput({\n type,\n onSubmit,\n}: {\n type: MediaType;\n onSubmit: (url: string) => void;\n}) {\n const [url, setUrl] = useState(\"\");\n const [error, setError] = useState<string>(\"\");\n\n const tryAdd = async () => {\n const trimmed = url.trim();\n if (!trimmed) return;\n\n if (!isValidUrl(trimmed)) {\n setError(\"Enter a valid URL\");\n return;\n }\n\n if (!matchesType(trimmed, type)) {\n setError(`URL must be a ${type} (${EXTENSIONS[type].join(\", \")})`);\n return;\n }\n\n setError(\"\");\n\n onSubmit(trimmed);\n setUrl(\"\");\n };\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n void tryAdd();\n }\n };\n\n return (\n <div>\n <div className=\"flex-container\">\n <input\n type=\"url\"\n placeholder={`Paste ${type} URL...`}\n value={url}\n onChange={(e) => setUrl(e.target.value)}\n onKeyDown={onKeyDown}\n className=\"input w-full\"\n />\n <button\n className=\"btn-ghost\"\n onClick={() => void tryAdd()}\n aria-label={`Add ${type} by URL`}\n >\n <Plus size={16} />\n </button>\n </div>\n {error ? <span className=\"text-error\">{error}</span> : null}\n </div>\n );\n}\n","import { createContext, useContext, useEffect, useState, ReactNode } from \"react\";\nimport type { MediaItem } from \"@twick/video-editor\";\nimport { getMediaManager, initializeDefaultVideos } from \"../components/shared\";\n\ntype MediaType = \"video\" | \"audio\" | \"image\";\n\ninterface MediaState {\n items: MediaItem[];\n searchQuery: string;\n isLoading: boolean;\n}\n\ninterface MediaContextType {\n videoState: MediaState;\n audioState: MediaState;\n imageState: MediaState;\n setSearchQuery: (type: MediaType, query: string) => void;\n addItem: (type: MediaType, item: MediaItem) => void;\n}\n\nconst initialMediaState: MediaState = {\n items: [],\n searchQuery: \"\",\n isLoading: false,\n};\n\nconst MediaContext = createContext<MediaContextType | null>(null);\n\nexport function MediaProvider({ children }: { children: ReactNode }) {\n const [videoState, setVideoState] = useState<MediaState>(initialMediaState);\n const [audioState, setAudioState] = useState<MediaState>(initialMediaState);\n const [imageState, setImageState] = useState<MediaState>(initialMediaState);\n const mediaManager = getMediaManager();\n\n const getStateAndSetter = (type: MediaType): [MediaState, (state: MediaState) => void] => {\n switch (type) {\n case \"video\":\n return [videoState, setVideoState];\n case \"audio\":\n return [audioState, setAudioState];\n case \"image\":\n return [imageState, setImageState];\n }\n };\n\n const loadItems = async (type: MediaType, query: string) => {\n const [state, setState] = getStateAndSetter(type);\n \n setState({ ...state, isLoading: true });\n try {\n const results = await mediaManager.search({\n query,\n type,\n });\n setState({\n items: results,\n searchQuery: query,\n isLoading: false,\n });\n } catch (error) {\n console.error(`Error loading ${type} items:`, error);\n setState({\n ...state,\n isLoading: false,\n });\n }\n };\n\n // Initialize default videos and load initial data for each type\n useEffect(() => {\n const initialize = async () => {\n // Initialize default videos first\n await initializeDefaultVideos();\n // Then load all media items\n loadItems(\"video\", \"\");\n loadItems(\"audio\", \"\");\n loadItems(\"image\", \"\");\n };\n initialize();\n }, []);\n\n const setSearchQuery = (type: MediaType, query: string) => {\n const [state, setState] = getStateAndSetter(type);\n setState({ ...state, searchQuery: query });\n loadItems(type, query);\n };\n\n const addItem = (type: MediaType, newItem: MediaItem) => {\n const [state, setState] = getStateAndSetter(type);\n setState({\n ...state,\n items: [...state.items, newItem],\n });\n };\n\n return (\n <MediaContext.Provider\n value={{\n videoState,\n audioState,\n imageState,\n setSearchQuery,\n addItem,\n }}\n >\n {children}\n </MediaContext.Provider>\n );\n}\n\nexport function useMedia(type: MediaType) {\n const context = useContext(MediaContext);\n if (!context) {\n throw new Error(\"useMedia must be used within a MediaProvider\");\n }\n\n const state = context[`${type}State`];\n return {\n items: state.items,\n searchQuery: state.searchQuery,\n isLoading: state.isLoading,\n setSearchQuery: (query: string) => context.setSearchQuery(type, query),\n addItem: (item: MediaItem) => context.addItem(type, item),\n };\n}\n","import {\n TrackElement,\n VideoElement,\n AudioElement,\n ImageElement,\n Size,\n} from \"@twick/timeline\";\nimport type { MediaItem } from \"@twick/video-editor\";\nimport { getMediaManager } from \"../components/shared\";\nimport { useMedia } from \"../context/media-context\";\n\nexport interface MediaPanelState {\n items: MediaItem[];\n searchQuery: string;\n isLoading: boolean;\n acceptFileTypes: string[];\n}\n\nexport interface MediaPanelActions {\n setSearchQuery: (query: string) => void;\n handleSelection: (item: MediaItem, forceAdd?: boolean) => void;\n handleFileUpload: (fileData: { file: File; blobUrl: string }) => void;\n}\n\nexport type MediaType = \"video\" | \"audio\" | \"image\";\n\nconst mediaConfigs = {\n video: {\n acceptFileTypes: [\"video/*\"] as string[],\n createElement: (url: string, parentSize: Size) =>\n new VideoElement(url, parentSize),\n updateElement: async (element: TrackElement, url: string) => {\n if (element instanceof VideoElement) {\n element.setSrc(url);\n await element.updateVideoMeta();\n }\n },\n },\n audio: {\n acceptFileTypes: [\"audio/*\"] as string[],\n createElement: (url: string, _parentSize: Size) => new AudioElement(url),\n updateElement: async (element: TrackElement, url: string) => {\n if (element instanceof AudioElement) {\n element.setSrc(url);\n await element.updateAudioMeta();\n }\n },\n },\n image: {\n acceptFileTypes: [\"image/*\"] as string[],\n createElement: (url: string, parentSize: Size) =>\n new ImageElement(url, parentSize),\n updateElement: async (element: TrackElement, url: string) => {\n if (element instanceof ImageElement) {\n element.setSrc(url);\n await element.updateImageMeta();\n }\n },\n },\n};\n\nexport const useMediaPanel = (\n type: MediaType,\n {\n selectedElement,\n addElement,\n updateElement,\n }: {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n },\n videoResolution: Size\n): MediaPanelState & MediaPanelActions => {\n const { items, searchQuery, setSearchQuery, addItem, isLoading } =\n useMedia(type);\n const mediaManager = getMediaManager();\n\n const handleSelection = async (item: MediaItem, forceAdd?: boolean) => {\n const config = mediaConfigs[type];\n if (forceAdd) {\n const element = config.createElement(item.url, videoResolution);\n addElement(element);\n } else {\n if (selectedElement) {\n await config.updateElement(selectedElement, item.url);\n updateElement(selectedElement);\n } else {\n const element = config.createElement(item.url, videoResolution);\n addElement(element);\n }\n }\n };\n\n const handleFileUpload = async (fileData: {\n file: File;\n blobUrl: string;\n }) => {\n const arrayBuffer = await fileData.file.arrayBuffer();\n const newItem = await mediaManager.addItem({\n name: fileData.file.name,\n url: fileData.blobUrl,\n type,\n arrayBuffer,\n metadata: {\n name: fileData.file.name,\n size: fileData.file.size,\n type: fileData.file.type,\n },\n });\n addItem(newItem);\n };\n\n const config = mediaConfigs[type];\n return {\n items,\n searchQuery,\n setSearchQuery,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes: config.acceptFileTypes,\n };\n};\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport type { MediaItem } from '@twick/video-editor';\n\nexport interface AudioPreviewState {\n playingAudio: string | null; // ID of currently playing audio\n audioElement: HTMLAudioElement | null;\n}\n\nexport interface AudioPreviewActions {\n togglePlayPause: (item: MediaItem) => void;\n stopPlayback: () => void;\n}\n\nexport const useAudioPreview = (): AudioPreviewState & AudioPreviewActions => {\n const [playingAudio, setPlayingAudio] = useState<string | null>(null);\n const audioRef = useRef<HTMLAudioElement | null>(null);\n\n // Cleanup audio element on unmount\n useEffect(() => {\n return () => {\n if (audioRef.current) {\n audioRef.current.pause();\n audioRef.current = null;\n }\n };\n }, []);\n\n const stopPlayback = useCallback(() => {\n if (audioRef.current) {\n audioRef.current.pause();\n audioRef.current = null;\n }\n setPlayingAudio(null);\n }, []);\n\n const togglePlayPause = useCallback((item: MediaItem) => {\n // If we're already playing this audio, stop it\n if (playingAudio === item.id) {\n stopPlayback();\n return;\n }\n\n // Stop any currently playing audio\n stopPlayback();\n\n // Start playing the new audio\n const audio = new Audio(item.url);\n audio.addEventListener('ended', stopPlayback);\n audio.play();\n audioRef.current = audio;\n setPlayingAudio(item.id);\n }, [playingAudio, stopPlayback]);\n\n return {\n playingAudio,\n audioElement: audioRef.current,\n togglePlayPause,\n stopPlayback,\n };\n};\n","/**\n * AudioPanel Component\n * \n * A panel for managing audio elements in the studio. Provides functionality\n * for searching, uploading, previewing, and adding audio files to the timeline.\n * \n * @component\n * @param {Object} props\n * @param {MediaItem[]} props.items - List of audio items to display\n * @param {string} props.searchQuery - Current search query\n * @param {string | null} props.playingAudio - ID of currently playing audio, if any\n * @param {(query: string) => void} props.onSearchChange - Handle search query changes\n * @param {(item: MediaItem) => void} props.onItemSelect - Handle audio item selection\n * @param {(item: MediaItem) => void} props.onPlayPause - Toggle audio preview playback\n * @param {(data: { file: File; blobUrl: string }) => void} props.onFileUpload - Handle file uploads\n * \n * @example\n * ```tsx\n * <AudioPanel\n * items={audioItems}\n * searchQuery=\"\"\n * playingAudio={null}\n * onSearchChange={setSearchQuery}\n * onItemSelect={handleSelect}\n * onPlayPause={togglePlayback}\n * onFileUpload={handleUpload}\n * />\n * ```\n */\n\nimport { Wand2, Plus, Volume2, Play, Pause } from \"lucide-react\";\nimport { TIMELINE_DROP_MEDIA_TYPE } from \"@twick/video-editor\";\nimport UrlInput from \"../shared/url-input\";\nimport type { AudioPanelProps } from \"../../types/media-panel\";\nimport { useAudioPreview } from \"../../hooks/use-audio-preview\";\n\n\nexport const AudioPanel = ({\n items,\n onItemSelect,\n onUrlAdd,\n isLoading,\n canLoadMore,\n onLoadMore,\n}: AudioPanelProps) => {\n const { playingAudio, togglePlayPause } = useAudioPreview();\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Audio Library</div>\n\n {/* Add by URL */}\n <div className=\"panel-section\">\n <UrlInput type=\"audio\" onSubmit={onUrlAdd} />\n </div>\n\n {/* Audio List */}\n <div className=\"media-content\">\n <div className=\"media-list\">\n {(items || []).map((item) => (\n <div\n key={item.id}\n draggable\n onDoubleClick={() => onItemSelect(item)}\n onDragStart={(e) => {\n e.dataTransfer.setData(\n TIMELINE_DROP_MEDIA_TYPE,\n JSON.stringify({ type: \"audio\", url: item.url })\n );\n e.dataTransfer.effectAllowed = \"copy\";\n }}\n className=\"media-list-item media-item-draggable\"\n >\n {/* Audio Info */}\n <div className=\"media-list-content\">\n {/* Play/Pause button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n togglePlayPause(item);\n }}\n className=\"media-action-btn\"\n >\n {playingAudio === item.id ? (\n <Pause className=\"icon-sm\" />\n ) : (\n <Play className=\"icon-sm\" />\n )}\n </button>\n\n {/* Audio Icon */}\n <div className={`media-list-icon ${playingAudio === item.id ? 'active' : ''}`}>\n <Volume2 className=\"icon-sm\" />\n </div>\n\n {/* Audio Title */}\n <div className=\"media-list-title\">\n {item.metadata?.title || item.metadata?.name}\n </div>\n\n {/* Quick Add button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n onItemSelect(item, true);\n }}\n className=\"media-action-btn\"\n >\n <Plus className=\"icon-sm\" />\n </button>\n </div>\n </div>\n ))}\n </div>\n\n {/* Empty state */}\n {items.length === 0 && (\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Wand2 className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">No audio files found</p>\n </div>\n </div>\n )}\n\n {onLoadMore && canLoadMore && (\n <div className=\"panel-section\">\n <button\n type=\"button\"\n className=\"btn-ghost w-full\"\n onClick={onLoadMore}\n disabled={isLoading}\n >\n {isLoading ? \"Loading...\" : \"Load more\"}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n};","import { Search } from \"lucide-react\";\n\nconst SearchInput = ({\n searchQuery,\n setSearchQuery,\n}: {\n searchQuery: string;\n setSearchQuery: (query: string) => void;\n}) => {\n return (\n <div className=\"search-container\">\n <input\n type=\"text\"\n placeholder=\"Search media...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"input search-input w-full\"\n />\n <Search className=\"search-icon\" />\n </div>\n );\n};\n\nexport default SearchInput;\n","import type {\n AssetLibrary,\n AssetListParams,\n AssetProviderConfig,\n MediaItem,\n} from \"@twick/video-editor\";\nimport { getMediaManager } from \"../components/shared\";\n\ninterface Paginated<T> {\n items: T[];\n page: number;\n pageSize: number;\n total: number;\n}\n\nconst DEFAULT_PAGE_SIZE = 50;\n\nasync function listUserAssets(params: AssetListParams): Promise<Paginated<MediaItem>> {\n const mediaManager = getMediaManager();\n const all = await mediaManager.search({\n query: params.query,\n type: params.type,\n });\n\n const page = params.page ?? 1;\n const pageSize = params.pageSize ?? DEFAULT_PAGE_SIZE;\n const start = (page - 1) * pageSize;\n const end = start + pageSize;\n\n return {\n items: all.slice(start, end),\n page,\n pageSize,\n total: all.length,\n };\n}\n\nasync function listPublicAssets(params: AssetListParams): Promise<Paginated<MediaItem>> {\n const page = params.page ?? 1;\n const pageSize = params.pageSize ?? DEFAULT_PAGE_SIZE;\n\n const searchParams = new URLSearchParams();\n searchParams.set(\"source\", \"public\");\n if (params.type) searchParams.set(\"type\", params.type);\n if (params.query) searchParams.set(\"query\", params.query);\n if (params.provider) searchParams.set(\"provider\", params.provider);\n searchParams.set(\"page\", String(page));\n searchParams.set(\"pageSize\", String(pageSize));\n\n const res = await fetch(`/api/assets/search?${searchParams.toString()}`);\n if (!res.ok) {\n throw new Error(`Failed to search public assets (${res.status})`);\n }\n\n const data = (await res.json()) as Paginated<any>;\n\n const items: MediaItem[] = (data.items || []).map((asset: any) => ({\n id: asset.id,\n name: asset.name,\n type: asset.type,\n url: asset.url,\n previewUrl: asset.previewUrl,\n thumbnail: asset.previewUrl ?? asset.thumbnail,\n waveformUrl: asset.waveformUrl,\n duration: asset.duration,\n width: asset.width,\n height: asset.height,\n sizeBytes: asset.sizeBytes,\n source: asset.source,\n origin: asset.origin,\n provider: asset.provider,\n providerId: asset.providerId,\n providerUrl: asset.providerUrl,\n attribution: asset.attribution,\n tags: asset.tags,\n metadata: asset.metadata,\n }));\n\n return {\n items,\n page: data.page ?? page,\n pageSize: data.pageSize ?? pageSize,\n total: data.total ?? items.length,\n };\n}\n\nconst studioAssetLibrary: AssetLibrary = {\n async listAssets(params: AssetListParams): Promise<Paginated<MediaItem>> {\n if (params.source === \"user\") {\n return listUserAssets(params);\n }\n return listPublicAssets(params);\n },\n\n async getAsset(id: string): Promise<MediaItem | null> {\n const mediaManager = getMediaManager();\n const item = await mediaManager.getItem(id);\n return item ?? null;\n },\n\n async uploadAsset(\n file: File,\n options?: {\n type?: \"video\" | \"audio\" | \"image\";\n metadata?: Record<string, unknown>;\n }\n ): Promise<MediaItem> {\n const mediaManager = getMediaManager();\n const arrayBuffer = await file.arrayBuffer();\n const type = options?.type ?? file.type.split(\"/\")[0];\n\n const item = await mediaManager.addItem({\n name: file.name,\n url: URL.createObjectURL(new Blob([arrayBuffer], { type: file.type })),\n type,\n arrayBuffer,\n metadata: {\n ...(options?.metadata ?? {}),\n name: file.name,\n size: file.size,\n type: file.type,\n source: \"upload\",\n },\n });\n\n return item;\n },\n\n async deleteAsset(id: string): Promise<void> {\n const mediaManager = getMediaManager();\n await mediaManager.deleteItem(id);\n },\n\n async listPublicProviders(): Promise<AssetProviderConfig[]> {\n const res = await fetch(\"/api/assets/providers/config\");\n if (!res.ok) {\n throw new Error(`Failed to load asset providers (${res.status})`);\n }\n const data = (await res.json()) as { providers?: AssetProviderConfig[] };\n return data.providers ?? [];\n },\n};\n\nexport const getAssetLibrary = () => studioAssetLibrary;\n\n","import { useEffect, useMemo, useState } from \"react\";\nimport { useMediaPanel } from \"../../hooks/use-media-panel\";\nimport { AudioPanel } from \"../panel/audio-panel\";\nimport type { PanelProps } from \"../../types\";\nimport { useMedia } from \"../../context/media-context\";\nimport { getMediaManager, CloudMediaUpload } from \"../shared\";\nimport SearchInput from \"../shared/search-input\";\nimport type { AssetProviderConfig, MediaItem } from \"@twick/video-editor\";\nimport { getAssetLibrary } from \"../../helpers/asset-library\";\nimport { throttle } from \"@twick/video-editor\";\n\nexport const AudioPanelContainer = (props: PanelProps) => {\n const [activeSource, setActiveSource] = useState<\"user\" | \"public\">(\"user\");\n\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n className={`btn-ghost w-full ${activeSource === \"user\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"user\")}\n >\n My assets\n </button>\n <button\n type=\"button\"\n className={`btn-ghost w-full ${activeSource === \"public\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"public\")}\n >\n Public\n </button>\n </div>\n </div>\n\n {activeSource === \"user\" ? (\n <AudioUserAssetsSection {...props} />\n ) : (\n <AudioPublicAssetsSection />\n )}\n </>\n );\n};\n\nfunction AudioUserAssetsSection(props: PanelProps) {\n const { addItem } = useMedia(\"audio\");\n const mediaManager = getMediaManager();\n const {\n items,\n searchQuery,\n setSearchQuery,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes,\n } = useMediaPanel(\n \"audio\",\n {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution,\n );\n\n const onUrlAdd = async (url: string) => {\n const nameFromUrl = (() => {\n try {\n const u = new URL(url);\n const parts = u.pathname.split(\"/\").filter(Boolean);\n return decodeURIComponent(parts[parts.length - 1] || url);\n } catch {\n return url;\n }\n })();\n\n const newItem = await mediaManager.addItem({\n name: nameFromUrl,\n url,\n type: \"audio\",\n metadata: { source: \"url\" },\n });\n addItem(newItem);\n };\n\n const onCloudUploadSuccess = async (url: string, file: File) => {\n const newItem = await mediaManager.addItem({\n name: file.name,\n url,\n type: \"audio\",\n metadata: { source: props.uploadConfig?.provider ?? \"s3\" },\n });\n addItem(newItem);\n };\n\n return (\n <>\n {props.uploadConfig && (\n <div className=\"flex panel-section\">\n <CloudMediaUpload\n uploadApiUrl={props.uploadConfig.uploadApiUrl}\n provider={props.uploadConfig.provider}\n accept=\"audio/*\"\n onSuccess={onCloudUploadSuccess}\n buttonText=\"Upload audio\"\n className=\"btn-ghost w-full\"\n />\n </div>\n )}\n <AudioPanel\n items={items}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onItemSelect={handleSelection}\n onFileUpload={handleFileUpload}\n isLoading={isLoading}\n acceptFileTypes={acceptFileTypes}\n onUrlAdd={onUrlAdd}\n />\n </>\n );\n}\n\nfunction AudioPublicAssetsSection() {\n const assetLibrary = getAssetLibrary();\n const [providerConfigs, setProviderConfigs] = useState<AssetProviderConfig[]>(\n [],\n );\n const [activeProviderId, setActiveProviderId] = useState<string | \"all\">(\n \"all\",\n );\n const [publicItems, setPublicItems] = useState<MediaItem[]>([]);\n const [publicSearchQuery, setPublicSearchQuery] = useState(\"\");\n const [isPublicLoading, setIsPublicLoading] = useState(false);\n\n useEffect(() => {\n const loadProviders = async () => {\n try {\n const configs = await assetLibrary.listPublicProviders();\n // Only show providers that actually support audio\n setProviderConfigs(\n configs.filter((c) => c.supportedTypes?.includes(\"audio\")),\n );\n } catch (err) {\n console.error(\"Failed to load asset providers\", err);\n }\n };\n void loadProviders();\n }, [assetLibrary]);\n\n const loadPublicAssets = async (query: string) => {\n setIsPublicLoading(true);\n try {\n const result = await assetLibrary.listAssets({\n source: \"public\",\n type: \"audio\",\n query,\n provider: activeProviderId === \"all\" ? undefined : activeProviderId,\n });\n setPublicItems(result.items);\n } catch (err) {\n console.error(\"Failed to load public audio assets\", err);\n setPublicItems([]);\n } finally {\n setIsPublicLoading(false);\n }\n };\n\n const throttledLoadPublicAssets = useMemo(\n () => throttle(loadPublicAssets, 1000),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [assetLibrary, activeProviderId],\n );\n\n useEffect(() => {\n if (publicSearchQuery) {\n void throttledLoadPublicAssets(publicSearchQuery);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeProviderId, publicSearchQuery]);\n\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"property-row\">\n <div className=\"property-row-label\">\n <span className=\"property-label\">Provider</span>\n </div>\n <div className=\"property-row-control\">\n <select\n className=\"select-dark\"\n value={activeProviderId}\n onChange={(e) =>\n setActiveProviderId(e.target.value as string | \"all\")\n }\n >\n <option value=\"all\">All providers</option>\n {providerConfigs\n .filter((p) => p.enabled)\n .map((p) => (\n <option key={p.id} value={p.id}>\n {p.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"property-row-control\">\n <SearchInput\n searchQuery={publicSearchQuery}\n setSearchQuery={(q) => {\n setPublicSearchQuery(q);\n }}\n />\n </div>\n </div>\n <AudioPanel\n items={publicItems}\n searchQuery={publicSearchQuery}\n onSearchChange={setPublicSearchQuery}\n onItemSelect={() => { }}\n onFileUpload={() => { }}\n isLoading={isPublicLoading}\n acceptFileTypes={[]}\n onUrlAdd={() => { }}\n />\n </>\n );\n}\n","/**\n * ImagePanel Component\n *\n * A panel for managing image elements in the studio. Provides functionality\n * for searching, uploading, previewing, and adding image files to the timeline.\n * Features a grid layout with image thumbnails and hover actions.\n *\n * @component\n * @param {Object} props\n * @param {MediaItem[]} props.items - List of image items to display\n * @param {string} props.searchQuery - Current search query\n * @param {(query: string) => void} props.setSearchQuery - Handle search query changes\n * @param {(item: MediaItem) => void} props.handleSelection - Handle image item selection\n * @param {(data: { file: File; blobUrl: string }) => void} props.handleFileUpload - Handle file uploads\n *\n * @example\n * ```tsx\n * <ImagePanel\n * items={imageItems}\n * searchQuery=\"\"\n * setSearchQuery={setSearchQuery}\n * handleSelection={handleSelect}\n * handleFileUpload={handleUpload}\n * />\n * ```\n */\n\nimport { Wand2, Plus } from \"lucide-react\";\nimport type { MediaItem } from \"@twick/video-editor\";\nimport { TIMELINE_DROP_MEDIA_TYPE } from \"@twick/video-editor\";\nimport type { ImagePanelProps } from \"../../types/media-panel\";\nimport UrlInput from \"../shared/url-input\";\n\nexport function ImagePanel({\n items,\n onItemSelect,\n onUrlAdd,\n isLoading,\n canLoadMore,\n onLoadMore,\n showAddByUrl = true,\n}: ImagePanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Image Library</div>\n\n {/* Add by URL */}\n {showAddByUrl && (\n <div className=\"panel-section\">\n <UrlInput type=\"image\" onSubmit={onUrlAdd} />\n </div>\n )}\n\n {/* Media Grid */}\n <div className=\"media-content\">\n <div className=\"media-grid\">\n {(items || []).map((item: MediaItem) => (\n <div\n key={item.id}\n draggable\n onDoubleClick={() => onItemSelect(item)}\n onDragStart={(e) => {\n e.dataTransfer.setData(\n TIMELINE_DROP_MEDIA_TYPE,\n JSON.stringify({ type: \"image\", url: item.url })\n );\n e.dataTransfer.effectAllowed = \"copy\";\n }}\n className=\"media-item media-item-draggable\"\n >\n <img src={item.url} alt=\"\" className=\"media-item-content\" />\n <div className=\"media-actions media-actions-corner\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n onItemSelect(item, true);\n }}\n className=\"media-action-btn\"\n >\n <Plus className=\"icon-sm\" />\n </button>\n </div>\n </div>\n ))}\n </div>\n\n {/* Empty state */}\n {items.length === 0 && (\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Wand2 className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">No images found</p>\n </div>\n </div>\n )}\n\n {onLoadMore && canLoadMore && (\n <div className=\"panel-section\">\n <button\n type=\"button\"\n className=\"btn-ghost w-full\"\n onClick={onLoadMore}\n disabled={isLoading}\n >\n {isLoading ? \"Loading...\" : \"Load more\"}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport type { PanelProps } from \"../../types\";\nimport { ImagePanel } from \"../panel/image-panel\";\nimport { useMediaPanel } from \"../../hooks/use-media-panel\";\nimport { useMedia } from \"../../context/media-context\";\nimport { getMediaManager, CloudMediaUpload } from \"../shared\";\nimport SearchInput from \"../shared/search-input\";\nimport { throttle, type AssetProviderConfig, type MediaItem } from \"@twick/video-editor\";\nimport { getAssetLibrary } from \"../../helpers/asset-library\";\n\nexport function ImagePanelContainer(props: PanelProps) {\n const [activeSource, setActiveSource] = useState<\"user\" | \"public\">(\"user\");\n\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n className={`btn-ghost w-full ${\n activeSource === \"user\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"user\")}\n >\n My assets\n </button>\n <button\n type=\"button\"\n className={`btn-ghost w-full ${\n activeSource === \"public\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"public\")}\n >\n Public\n </button>\n </div>\n </div>\n\n {activeSource === \"user\" ? (\n <ImageUserAssetsSection {...props} />\n ) : (\n <ImagePublicAssetsSection />\n )}\n </>\n );\n}\n\nfunction ImageUserAssetsSection(props: PanelProps) {\n const { addItem } = useMedia(\"image\");\n const mediaManager = getMediaManager();\n const [page, setPage] = useState(1);\n const PAGE_SIZE = 30;\n const {\n items,\n searchQuery,\n setSearchQuery,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes,\n } = useMediaPanel(\n \"image\",\n {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution,\n );\n\n const onUrlAdd = async (url: string) => {\n const nameFromUrl = (() => {\n try {\n const u = new URL(url);\n const parts = u.pathname.split(\"/\").filter(Boolean);\n return decodeURIComponent(parts[parts.length - 1] || url);\n } catch {\n return url;\n }\n })();\n\n const newItem = await mediaManager.addItem({\n name: nameFromUrl,\n url,\n type: \"image\",\n metadata: { source: \"url\" },\n });\n addItem(newItem);\n };\n\n const onCloudUploadSuccess = async (url: string, file: File) => {\n const newItem = await mediaManager.addItem({\n name: file.name,\n url,\n type: \"image\",\n metadata: { source: props.uploadConfig?.provider ?? \"s3\" },\n });\n addItem(newItem);\n };\n\n const visibleItems = items.slice(0, page * PAGE_SIZE);\n const canLoadMore = items.length > visibleItems.length;\n\n useEffect(() => {\n setPage(1);\n }, [searchQuery]);\n\n return (\n <>\n {props.uploadConfig && (\n <div className=\"flex panel-section\">\n <CloudMediaUpload\n uploadApiUrl={props.uploadConfig.uploadApiUrl}\n provider={props.uploadConfig.provider}\n accept=\"image/*\"\n onSuccess={onCloudUploadSuccess}\n buttonText=\"Upload image\"\n className=\"btn-ghost w-full\"\n />\n </div>\n )}\n <ImagePanel\n items={visibleItems}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onItemSelect={handleSelection}\n onFileUpload={handleFileUpload}\n isLoading={isLoading}\n acceptFileTypes={acceptFileTypes}\n onUrlAdd={onUrlAdd}\n canLoadMore={canLoadMore}\n onLoadMore={() => setPage((prev) => prev + 1)}\n />\n </>\n );\n}\n\nfunction ImagePublicAssetsSection() {\n const assetLibrary = getAssetLibrary();\n const [providerConfigs, setProviderConfigs] = useState<AssetProviderConfig[]>(\n [],\n );\n const [activeProviderId, setActiveProviderId] = useState<string | \"all\">(\n \"all\",\n );\n const [publicItems, setPublicItems] = useState<MediaItem[]>([]);\n const [publicSearchQuery, setPublicSearchQuery] = useState(\"nature\");\n const [isPublicLoading, setIsPublicLoading] = useState(false);\n const [page, setPage] = useState(1);\n const [hasMore, setHasMore] = useState(true);\n const PAGE_SIZE = 20;\n\n useEffect(() => {\n const loadProviders = async () => {\n try {\n const configs = await assetLibrary.listPublicProviders();\n // Only show providers that actually support images\n setProviderConfigs(\n configs.filter((c) => c.supportedTypes?.includes(\"image\")),\n );\n } catch (err) {\n console.error(\"Failed to load asset providers\", err);\n }\n };\n void loadProviders();\n }, [assetLibrary]);\n\n const loadPublicAssets = async (query: string) => {\n setIsPublicLoading(true);\n try {\n const result = await assetLibrary.listAssets({\n source: \"public\",\n type: \"image\",\n query,\n provider: activeProviderId === \"all\" ? undefined : activeProviderId,\n page: 1,\n pageSize: PAGE_SIZE,\n });\n setPublicItems(result.items);\n setPage(1);\n setHasMore(result.items.length === PAGE_SIZE);\n } catch (err) {\n console.error(\"Failed to load public image assets\", err);\n setPublicItems([]);\n } finally {\n setIsPublicLoading(false);\n }\n };\n\n const throttledLoadPublicAssets = useMemo(\n () => throttle(loadPublicAssets, 1000),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [assetLibrary, activeProviderId],\n );\n\n useEffect(() => {\n if (publicSearchQuery) {\n void throttledLoadPublicAssets(publicSearchQuery);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeProviderId, publicSearchQuery]);\n\n const loadMore = async () => {\n if (!hasMore || isPublicLoading) return;\n const nextPage = page + 1;\n setIsPublicLoading(true);\n try {\n const result = await assetLibrary.listAssets({\n source: \"public\",\n type: \"image\",\n query: publicSearchQuery,\n provider: activeProviderId === \"all\" ? undefined : activeProviderId,\n page: nextPage,\n pageSize: PAGE_SIZE,\n });\n setPublicItems((prev) => [...prev, ...result.items]);\n setPage(nextPage);\n setHasMore(result.items.length === PAGE_SIZE);\n } catch (err) {\n console.error(\"Failed to load more public image assets\", err);\n } finally {\n setIsPublicLoading(false);\n }\n };\n\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"property-row\">\n <div className=\"property-row-label\">\n <span className=\"property-label\">Provider</span>\n </div>\n <div className=\"property-row-control\">\n <select\n className=\"select-dark\"\n value={activeProviderId}\n onChange={(e) =>\n setActiveProviderId(e.target.value as string | \"all\")\n }\n >\n <option value=\"all\">All providers</option>\n {providerConfigs\n .filter((p) => p.enabled)\n .map((p) => (\n <option key={p.id} value={p.id}>\n {p.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"property-row-control\">\n <SearchInput\n searchQuery={publicSearchQuery}\n setSearchQuery={(q) => {\n setPublicSearchQuery(q);\n }}\n />\n </div>\n </div>\n <ImagePanel\n items={publicItems}\n searchQuery={publicSearchQuery}\n onSearchChange={setPublicSearchQuery}\n onItemSelect={() => {}}\n onFileUpload={() => {}}\n isLoading={isPublicLoading}\n acceptFileTypes={[]}\n onUrlAdd={() => {}}\n showAddByUrl={false}\n canLoadMore={hasMore}\n onLoadMore={loadMore}\n />\n </>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport type { MediaItem } from '@twick/video-editor';\n\nexport interface VideoPreviewState {\n playingVideo: string | null; // ID of currently playing video\n videoElement: HTMLVideoElement | null;\n}\n\nexport interface VideoPreviewActions {\n togglePlayPause: (item: MediaItem, videoElement: HTMLVideoElement) => void;\n stopPlayback: () => void;\n}\n\nexport const useVideoPreview = (): VideoPreviewState & VideoPreviewActions => {\n const [playingVideo, setPlayingVideo] = useState<string | null>(null);\n const videoRef = useRef<HTMLVideoElement | null>(null);\n\n // Cleanup video element on unmount\n useEffect(() => {\n return () => {\n if (videoRef.current) {\n videoRef.current.pause();\n videoRef.current = null;\n }\n };\n }, []);\n\n const stopPlayback = useCallback(() => {\n if (videoRef.current) {\n videoRef.current.pause();\n videoRef.current = null;\n }\n setPlayingVideo(null);\n }, []);\n\n const togglePlayPause = useCallback((item: MediaItem, videoElement: HTMLVideoElement) => {\n // If we're already playing this video, pause it\n if (playingVideo === item.id) {\n videoElement.pause();\n stopPlayback();\n return;\n }\n\n // Stop any currently playing video\n stopPlayback();\n\n // Start playing the new video\n videoElement.currentTime = 0; // Reset to start\n videoElement.play();\n videoRef.current = videoElement;\n setPlayingVideo(item.id);\n\n // Add ended event listener\n videoElement.addEventListener('ended', stopPlayback, { once: true });\n }, [playingVideo, stopPlayback]);\n\n return {\n playingVideo,\n videoElement: videoRef.current,\n togglePlayPause,\n stopPlayback,\n };\n};","/**\n * VideoPanel Component\n * \n * A panel for managing video elements in the studio. Provides functionality\n * for searching, uploading, previewing, and adding video files to the timeline.\n * Features a grid layout with video thumbnails and hover actions.\n * \n * @component\n * @param {Object} props\n * @param {MediaItem[]} props.items - List of video items to display\n * @param {string} props.searchQuery - Current search query\n * @param {(query: string) => void} props.setSearchQuery - Handle search query changes\n * @param {(item: MediaItem) => void} props.handleSelection - Handle video item selection\n * @param {(data: { file: File; blobUrl: string }) => void} props.handleFileUpload - Handle file uploads\n * \n * @example\n * ```tsx\n * <VideoPanel\n * items={videoItems}\n * searchQuery=\"\"\n * setSearchQuery={setSearchQuery}\n * handleSelection={handleSelect}\n * handleFileUpload={handleUpload}\n * />\n * ```\n */\n\nimport { Wand2, Plus, Play, Pause } from \"lucide-react\";\nimport type { MediaItem } from \"@twick/video-editor\";\nimport { TIMELINE_DROP_MEDIA_TYPE } from \"@twick/video-editor\";\nimport type { VideoPanelProps } from \"../../types/media-panel\";\nimport { useVideoPreview } from \"../../hooks/use-video-preview\";\nimport UrlInput from \"../shared/url-input\";\n\n\nexport function VideoPanel({\n items,\n onItemSelect,\n onUrlAdd,\n showAddByUrl = true,\n isLoading,\n canLoadMore,\n onLoadMore,\n}: VideoPanelProps) {\n const { playingVideo, togglePlayPause } = useVideoPreview();\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Video Library</div>\n \n {/* Add by URL */}\n {showAddByUrl && (\n <div className=\"flex panel-section\">\n <UrlInput type=\"video\" onSubmit={onUrlAdd} />\n </div>\n )}\n\n {/* Media Grid */}\n <div className=\"media-content\">\n <div className=\"media-grid\">\n {(items || []).map((item: MediaItem) => (\n <div\n key={item.id}\n draggable\n onDoubleClick={() => onItemSelect(item)}\n onDragStart={(e) => {\n e.dataTransfer.setData(\n TIMELINE_DROP_MEDIA_TYPE,\n JSON.stringify({ type: \"video\", url: item.url })\n );\n e.dataTransfer.effectAllowed = \"copy\";\n }}\n className=\"media-item media-item-draggable\"\n >\n <video\n src={item.url}\n poster={item.thumbnail}\n className=\"media-item-content\"\n ref={(el) => {\n if (el) {\n el.addEventListener('ended', () => {\n el.currentTime = 0;\n }, { once: true });\n }\n }}\n />\n\n {/* Duration */}\n {/* <div className=\"media-duration\">\n 0:13\n </div> */}\n\n {/* Corner play/pause control */}\n <div className=\"media-actions media-actions-corner\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n const videoEl =\n e.currentTarget.parentElement?.parentElement?.querySelector(\"video\");\n if (videoEl) {\n togglePlayPause(item, videoEl);\n }\n }}\n className=\"media-action-btn\"\n >\n {playingVideo === item.id ? (\n <Pause className=\"icon-sm\" />\n ) : (\n <Play className=\"icon-sm\" />\n )}\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n onItemSelect(item, true);\n }}\n className=\"media-action-btn\"\n >\n <Plus className=\"icon-sm\" />\n </button>\n </div>\n </div>\n ))}\n </div>\n\n {/* Empty state */}\n {items.length === 0 && (\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Wand2 className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">No videos found</p>\n </div>\n </div>\n )}\n\n {onLoadMore && canLoadMore && (\n <div className=\"panel-section\">\n <button\n type=\"button\"\n className=\"btn-ghost w-full\"\n onClick={onLoadMore}\n disabled={isLoading}\n >\n {isLoading ? \"Loading...\" : \"Load more\"}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}","import { useEffect, useMemo, useState } from \"react\";\nimport type { PanelProps } from \"../../types\";\nimport { VideoPanel } from \"../panel/video-panel\";\nimport { useMediaPanel } from \"../../hooks/use-media-panel\";\nimport { useMedia } from \"../../context/media-context\";\nimport { getMediaManager, CloudMediaUpload } from \"../shared\";\nimport SearchInput from \"../shared/search-input\";\nimport type { AssetProviderConfig, MediaItem } from \"@twick/video-editor\";\nimport { throttle } from \"@twick/video-editor\";\nimport { getAssetLibrary } from \"../../helpers/asset-library\";\n\nexport function VideoPanelContainer(props: PanelProps) {\n const [activeSource, setActiveSource] = useState<\"user\" | \"public\">(\"user\");\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n className={`btn-ghost w-full ${activeSource === \"user\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"user\")}\n >\n My assets\n </button>\n <button\n type=\"button\"\n className={`btn-ghost w-full ${activeSource === \"public\" ? \"btn-primary\" : \"\"\n }`}\n onClick={() => setActiveSource(\"public\")}\n >\n Public\n </button>\n </div>\n </div>\n\n {activeSource === \"user\" ? (\n <VideoUserAssetsSection {...props} />\n ) : (\n <VideoPublicAssetsSection />\n )}\n </>\n );\n}\n\nfunction VideoUserAssetsSection(props: PanelProps) {\n const { addItem } = useMedia(\"video\");\n const mediaManager = getMediaManager();\n const [page, setPage] = useState(1);\n const PAGE_SIZE = 30;\n const {\n items,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes,\n } = useMediaPanel(\n \"video\",\n {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution,\n );\n\n const onUrlAdd = async (url: string) => {\n const nameFromUrl = (() => {\n try {\n const u = new URL(url);\n const parts = u.pathname.split(\"/\").filter(Boolean);\n return decodeURIComponent(parts[parts.length - 1] || url);\n } catch {\n return url;\n }\n })();\n\n const newItem = await mediaManager.addItem({\n name: nameFromUrl,\n url,\n type: \"video\",\n metadata: { source: \"url\" },\n });\n addItem(newItem);\n };\n\n const onCloudUploadSuccess = async (url: string, file: File) => {\n const newItem = await mediaManager.addItem({\n name: file.name,\n url,\n type: \"video\",\n metadata: { source: props.uploadConfig?.provider ?? \"s3\" },\n });\n addItem(newItem);\n };\n\n const visibleItems = items.slice(0, page * PAGE_SIZE);\n const canLoadMore = items.length > visibleItems.length;\n\n return (\n <>\n {props.uploadConfig && (\n <div className=\"flex panel-section\">\n <CloudMediaUpload\n uploadApiUrl={props.uploadConfig.uploadApiUrl}\n provider={props.uploadConfig.provider}\n accept=\"video/*\"\n onSuccess={onCloudUploadSuccess}\n buttonText=\"Upload video\"\n className=\"btn-ghost w-full\"\n />\n </div>\n )}\n <VideoPanel\n items={visibleItems}\n onItemSelect={handleSelection}\n onFileUpload={handleFileUpload}\n isLoading={isLoading}\n acceptFileTypes={acceptFileTypes}\n onUrlAdd={onUrlAdd}\n canLoadMore={canLoadMore}\n onLoadMore={() => setPage((prev) => prev + 1)}\n />\n </>\n );\n}\n\nfunction VideoPublicAssetsSection() {\n const assetLibrary = getAssetLibrary();\n const [providerConfigs, setProviderConfigs] = useState<AssetProviderConfig[]>(\n [],\n );\n const [activeProviderId, setActiveProviderId] = useState<string | \"all\">(\n \"all\",\n );\n const [publicItems, setPublicItems] = useState<MediaItem[]>([]);\n const [publicSearchQuery, setPublicSearchQuery] = useState(\"nature\");\n const [isPublicLoading, setIsPublicLoading] = useState(false);\n const [page, setPage] = useState(1);\n const [hasMore, setHasMore] = useState(true);\n const PAGE_SIZE = 10;\n\n useEffect(() => {\n const loadProviders = async () => {\n try {\n const configs = await assetLibrary.listPublicProviders();\n // Only show providers that actually support video\n setProviderConfigs(\n configs.filter((c) => c.supportedTypes?.includes(\"video\")),\n );\n } catch (err) {\n console.error(\"Failed to load asset providers\", err);\n }\n };\n void loadProviders();\n }, [assetLibrary]);\n\n const loadPublicAssets = async (query: string) => {\n setIsPublicLoading(true);\n try {\n const result = await assetLibrary.listAssets({\n source: \"public\",\n type: \"video\",\n query,\n page: 1,\n pageSize: PAGE_SIZE,\n provider: activeProviderId === \"all\" ? undefined : activeProviderId,\n });\n setPublicItems(result.items);\n setPage(1);\n setHasMore(result.items.length === PAGE_SIZE);\n } catch (err) {\n console.error(\"Failed to load public video assets\", err);\n setPublicItems([]);\n } finally {\n setIsPublicLoading(false);\n }\n };\n\n const throttledLoadPublicAssets = useMemo(\n () => throttle(loadPublicAssets, 1000),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [assetLibrary, activeProviderId],\n );\n\n useEffect(() => {\n void throttledLoadPublicAssets(publicSearchQuery);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeProviderId]);\n\n useEffect(() => {\n if (publicSearchQuery) {\n void throttledLoadPublicAssets(publicSearchQuery);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [publicSearchQuery]);\n\n const loadMore = async () => {\n if (!hasMore || isPublicLoading) return;\n const nextPage = page + 1;\n setIsPublicLoading(true);\n try {\n const result = await assetLibrary.listAssets({\n source: \"public\",\n type: \"video\",\n query: publicSearchQuery,\n page: nextPage,\n pageSize: PAGE_SIZE,\n provider: activeProviderId === \"all\" ? undefined : activeProviderId,\n });\n setPublicItems((prev) => [...prev, ...result.items]);\n setPage(nextPage);\n setHasMore(result.items.length === PAGE_SIZE);\n } catch (err) {\n console.error(\"Failed to load more public video assets\", err);\n } finally {\n setIsPublicLoading(false);\n }\n };\n\n return (\n <>\n <div className=\"panel-section\">\n <div className=\"property-row\">\n <div className=\"property-row-label\">\n <span className=\"property-label\">Provider</span>\n </div>\n <div className=\"property-row-control\">\n <select\n className=\"select-dark\"\n value={activeProviderId}\n onChange={(e) =>\n setActiveProviderId(e.target.value as string | \"all\")\n }\n >\n <option value=\"all\">All providers</option>\n {providerConfigs\n .filter((p) => p.enabled)\n .map((p) => (\n <option key={p.id} value={p.id}>\n {p.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"property-row-control\">\n <SearchInput\n searchQuery={publicSearchQuery}\n setSearchQuery={(q) => {\n setPublicSearchQuery(q);\n }}\n />\n </div>\n </div>\n <VideoPanel\n items={publicItems}\n onItemSelect={() => {\n // Selection handled via timeline; public items behave same as user items\n }}\n onFileUpload={() => { }}\n isLoading={isPublicLoading}\n acceptFileTypes={[]}\n onUrlAdd={() => { }}\n showAddByUrl={false}\n canLoadMore={hasMore}\n onLoadMore={loadMore}\n />\n </>\n );\n}\n","/**\n * TextPanel Component\n * \n * A panel for creating and editing text elements in the studio. Provides comprehensive\n * text styling options including font selection, size, colors, stroke, and shadow effects.\n * \n * @component\n * @param {Object} props\n * @param {string} props.textContent - Text content to display\n * @param {number} props.fontSize - Font size in pixels\n * @param {string} props.selectedFont - Selected font family\n * @param {boolean} props.isBold - Whether text is bold\n * @param {boolean} props.isItalic - Whether text is italic\n * @param {string} props.textColor - Text color in hex format\n * @param {string} props.strokeColor - Stroke color in hex format\n * @param {boolean} props.applyShadow - Whether to apply shadow effect\n * @param {string} props.shadowColor - Shadow color in hex format\n * @param {number} props.strokeWidth - Width of text stroke\n * @param {boolean} props.applyBackground - Whether to apply background behind text\n * @param {string} props.backgroundColor - Background color in hex (when applyBackground is true)\n * @param {number} props.backgroundOpacity - Background opacity 0-1 (when applyBackground is true)\n * @param {string[]} props.fonts - Available font options\n * @param {(text: string) => void} props.setTextContent - Update text content\n * @param {(size: number) => void} props.setFontSize - Update font size\n * @param {(font: string) => void} props.setSelectedFont - Update selected font\n * @param {(bold: boolean) => void} props.setIsBold - Toggle bold style\n * @param {(italic: boolean) => void} props.setIsItalic - Toggle italic style\n * @param {(color: string) => void} props.setTextColor - Update text color\n * @param {(color: string) => void} props.setStrokeColor - Update stroke color\n * @param {(apply: boolean) => void} props.setApplyShadow - Toggle shadow effect\n * @param {(color: string) => void} props.setShadowColor - Update shadow color\n * @param {(width: number) => void} props.setStrokeWidth - Update stroke width\n * @param {(apply: boolean) => void} props.setApplyBackground - Toggle background\n * @param {(color: string) => void} props.setBackgroundColor - Update background color\n * @param {(opacity: number) => void} props.setBackgroundOpacity - Update background opacity\n * @param {() => void} props.handleApplyChanges - Apply text element changes\n * \n * @example\n * ```tsx\n * <TextPanel\n * textContent=\"Sample Text\"\n * fontSize={48}\n * selectedFont=\"Arial\"\n * isBold={false}\n * isItalic={false}\n * textColor=\"#000000\"\n * strokeColor=\"#ffffff\"\n * applyShadow={false}\n * shadowColor=\"#000000\"\n * strokeWidth={0}\n * fonts={[\"Arial\", \"Times New Roman\"]}\n * setTextContent={setText}\n * setFontSize={setSize}\n * // ... other handlers\n * />\n * ```\n */\n\nimport type { TextPanelState, TextPanelActions } from \"../../hooks/use-text-panel\";\n\nexport type TextPanelProps = TextPanelState & TextPanelActions;\n\nexport function TextPanel({\n textContent,\n fontSize,\n selectedFont,\n isBold,\n isItalic,\n textColor,\n strokeColor,\n applyShadow,\n shadowColor,\n strokeWidth,\n applyBackground,\n backgroundColor,\n backgroundOpacity,\n fonts,\n operation,\n setTextContent,\n setFontSize,\n setSelectedFont,\n setIsBold,\n setIsItalic,\n setTextColor,\n setStrokeColor,\n setApplyShadow,\n setShadowColor,\n setStrokeWidth,\n setApplyBackground,\n setBackgroundColor,\n setBackgroundOpacity,\n handleApplyChanges,\n}: TextPanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Text</div>\n {/* Text Content */}\n <div className=\"flex panel-section\">\n <input\n type=\"text\"\n value={textContent}\n placeholder=\"Sample\"\n onChange={(e) => setTextContent(e.target.value)}\n className=\"input-dark\"\n />\n </div>\n\n {/* Font Size */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Font Size</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"8\"\n max=\"120\"\n value={fontSize}\n onChange={(e) => setFontSize(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{fontSize}px</span>\n </div>\n </div>\n\n {/* Font */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Font</label>\n <div className=\"font-controls\">\n <select\n value={selectedFont}\n onChange={(e) => setSelectedFont(e.target.value)}\n className=\"select-dark\"\n >\n {fonts.map((font) => (\n <option key={font} value={font}>\n {font}\n </option>\n ))}\n </select>\n <button\n onClick={() => setIsBold(!isBold)}\n className={`btn-icon ${isBold ? 'btn-icon-active' : ''}`}\n >\n B\n </button>\n <button\n onClick={() => setIsItalic(!isItalic)}\n className={`btn-icon ${isItalic ? 'btn-icon-active' : ''}`}\n >\n I\n </button>\n </div>\n </div>\n\n {/* Colors */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Colors</label>\n <div className=\"color-section\">\n {/* Text Color */}\n <div className=\"color-control\">\n <label className=\"label-small\">Text Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={textColor}\n onChange={(e) => setTextColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={textColor}\n onChange={(e) => setTextColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n {/* Stroke Color */}\n <div className=\"color-control\">\n <label className=\"label-small\">Stroke Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n {/* Apply Shadow */}\n <div className=\"checkbox-control\">\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={applyShadow}\n onChange={(e) => setApplyShadow(e.target.checked)}\n className=\"checkbox-purple\"\n />\n Apply Shadow\n </label>\n </div>\n\n {/* Shadow Color - Only shown when shadow is enabled */}\n {applyShadow && (\n <div className=\"color-control\">\n <label className=\"label-small\">Shadow Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={shadowColor}\n onChange={(e) => setShadowColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={shadowColor}\n onChange={(e) => setShadowColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Stroke Width */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Stroke Width</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"2\"\n step={0.1}\n value={strokeWidth}\n onChange={(e) => setStrokeWidth(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{strokeWidth}</span>\n </div>\n </div>\n\n {/* Background (optional) */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Background</label>\n <div className=\"color-section\">\n <div className=\"checkbox-control\">\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={applyBackground}\n onChange={(e) => setApplyBackground(e.target.checked)}\n className=\"checkbox-purple\"\n />\n Apply Background\n </label>\n </div>\n {applyBackground && (\n <>\n <div className=\"color-control\">\n <label className=\"label-small\">Background Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={backgroundColor}\n onChange={(e) => setBackgroundColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={backgroundColor}\n onChange={(e) => setBackgroundColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n <div className=\"panel-section\">\n <label className=\"label-small\">Background Opacity</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step={0.1}\n value={backgroundOpacity}\n onChange={(e) => setBackgroundOpacity(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{Math.round(backgroundOpacity * 100)}%</span>\n </div>\n </div>\n </>\n )}\n </div>\n </div>\n\n {/* Operation button (only for creation, not edits) */}\n {operation !== \"Apply Changes\" && (\n <div className=\"flex panel-section\">\n <button onClick={handleApplyChanges} className=\"btn-primary w-full\">\n {operation}\n </button>\n </div>\n )}\n </div>\n );\n}","import { useEffect, useState } from \"react\";\nimport { TextElement, TrackElement, type TextAlign } from \"@twick/timeline\";\nimport { AVAILABLE_TEXT_FONTS } from \"@twick/video-editor\";\n\nexport const DEFAULT_TEXT_PROPS = {\n text: \"Sample\",\n fontSize: 48,\n fontFamily: \"Poppins\",\n fontWeight: 400,\n fontStyle: \"normal\",\n textColor: \"#ffffff\",\n strokeColor: \"#4d4d4d\",\n strokeWidth: 0,\n applyShadow: false,\n shadowColor: \"#000000\",\n textAlign: \"center\" as TextAlign,\n shadowOffset: [0, 0],\n shadowBlur: 2,\n shadowOpacity: 1.0,\n};\n\nexport interface TextPanelState {\n textContent: string;\n fontSize: number;\n selectedFont: string;\n isBold: boolean;\n isItalic: boolean;\n textColor: string;\n strokeColor: string;\n applyShadow: boolean;\n shadowColor: string;\n strokeWidth: number;\n applyBackground: boolean;\n backgroundColor: string;\n backgroundOpacity: number;\n fonts: string[];\n operation: string;\n}\n\nexport interface TextPanelActions {\n setTextContent: (text: string) => void;\n setFontSize: (size: number) => void;\n setSelectedFont: (font: string) => void;\n setIsBold: (bold: boolean) => void;\n setIsItalic: (italic: boolean) => void;\n setTextColor: (color: string) => void;\n setStrokeColor: (color: string) => void;\n setApplyShadow: (shadow: boolean) => void;\n setShadowColor: (color: string) => void;\n setStrokeWidth: (width: number) => void;\n setApplyBackground: (apply: boolean) => void;\n setBackgroundColor: (color: string) => void;\n setBackgroundOpacity: (opacity: number) => void;\n handleApplyChanges: () => void;\n}\n\nexport const useTextPanel = ({\n selectedElement,\n addElement,\n updateElement,\n}: {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}): TextPanelState & TextPanelActions => {\n const [textContent, setTextContent] = useState(DEFAULT_TEXT_PROPS.text);\n const [fontSize, setFontSize] = useState(DEFAULT_TEXT_PROPS.fontSize);\n const [selectedFont, setSelectedFont] = useState(DEFAULT_TEXT_PROPS.fontFamily);\n const [isBold, setIsBold] = useState(DEFAULT_TEXT_PROPS.fontWeight === 700);\n const [isItalic, setIsItalic] = useState(DEFAULT_TEXT_PROPS.fontStyle === \"italic\");\n const [textColor, setTextColor] = useState(DEFAULT_TEXT_PROPS.textColor);\n const [strokeColor, setStrokeColor] = useState(DEFAULT_TEXT_PROPS.strokeColor);\n const [applyShadow, setApplyShadow] = useState(DEFAULT_TEXT_PROPS.applyShadow);\n const [shadowColor, setShadowColor] = useState(DEFAULT_TEXT_PROPS.shadowColor);\n const [strokeWidth, setStrokeWidth] = useState(DEFAULT_TEXT_PROPS.strokeWidth);\n const [applyBackground, setApplyBackground] = useState(false);\n const [backgroundColor, setBackgroundColor] = useState(\"#FACC15\");\n const [backgroundOpacity, setBackgroundOpacity] = useState(1);\n\n const fonts = Object.values(AVAILABLE_TEXT_FONTS);\n\n const applyLiveChangesToExistingText = (overrides: Partial<TextPanelState> = {}) => {\n if (!(selectedElement instanceof TextElement)) {\n return;\n }\n\n const textElement = selectedElement;\n\n const nextState: Pick<\n TextPanelState,\n | \"textContent\"\n | \"fontSize\"\n | \"selectedFont\"\n | \"isBold\"\n | \"isItalic\"\n | \"textColor\"\n | \"strokeColor\"\n | \"strokeWidth\"\n | \"applyShadow\"\n | \"shadowColor\"\n | \"applyBackground\"\n | \"backgroundColor\"\n | \"backgroundOpacity\"\n > = {\n textContent,\n fontSize,\n selectedFont,\n isBold,\n isItalic,\n textColor,\n strokeColor,\n strokeWidth,\n applyShadow,\n shadowColor,\n applyBackground,\n backgroundColor,\n backgroundOpacity,\n ...overrides,\n };\n\n textElement.setText(nextState.textContent);\n textElement.setFontSize(nextState.fontSize);\n textElement.setFontFamily(nextState.selectedFont);\n textElement.setFontWeight(nextState.isBold ? 700 : 400);\n textElement.setFontStyle(nextState.isItalic ? \"italic\" : \"normal\");\n textElement.setFill(nextState.textColor);\n textElement.setStrokeColor(nextState.strokeColor);\n textElement.setLineWidth(nextState.strokeWidth);\n textElement.setTextAlign(DEFAULT_TEXT_PROPS.textAlign);\n\n const nextProps = { ...textElement.getProps() };\n\n if (nextState.applyShadow) {\n nextProps.shadowColor = nextState.shadowColor;\n nextProps.shadowOffset = DEFAULT_TEXT_PROPS.shadowOffset;\n nextProps.shadowBlur = DEFAULT_TEXT_PROPS.shadowBlur;\n nextProps.shadowOpacity = DEFAULT_TEXT_PROPS.shadowOpacity;\n } else {\n nextProps.shadowColor = undefined;\n nextProps.shadowOffset = undefined;\n nextProps.shadowBlur = undefined;\n nextProps.shadowOpacity = undefined;\n }\n\n if (nextState.applyBackground) {\n nextProps.backgroundColor = nextState.backgroundColor;\n nextProps.backgroundOpacity = nextState.backgroundOpacity;\n } else {\n nextProps.backgroundColor = undefined;\n nextProps.backgroundOpacity = undefined;\n }\n\n textElement.setProps(nextProps);\n updateElement(textElement);\n };\n\n const handleTextContentChange = (text: string) => {\n setTextContent(text);\n applyLiveChangesToExistingText({ textContent: text });\n };\n\n const handleFontSizeChange = (size: number) => {\n setFontSize(size);\n applyLiveChangesToExistingText({ fontSize: size });\n };\n\n const handleSelectedFontChange = (font: string) => {\n setSelectedFont(font);\n applyLiveChangesToExistingText({ selectedFont: font });\n };\n\n const handleIsBoldChange = (bold: boolean) => {\n setIsBold(bold);\n applyLiveChangesToExistingText({ isBold: bold });\n };\n\n const handleIsItalicChange = (italic: boolean) => {\n setIsItalic(italic);\n applyLiveChangesToExistingText({ isItalic: italic });\n };\n\n const handleTextColorChange = (color: string) => {\n setTextColor(color);\n applyLiveChangesToExistingText({ textColor: color });\n };\n\n const handleStrokeColorChange = (color: string) => {\n setStrokeColor(color);\n applyLiveChangesToExistingText({ strokeColor: color });\n };\n\n const handleStrokeWidthChange = (width: number) => {\n setStrokeWidth(width);\n applyLiveChangesToExistingText({ strokeWidth: width });\n };\n\n const handleApplyShadowChange = (shadow: boolean) => {\n setApplyShadow(shadow);\n applyLiveChangesToExistingText({ applyShadow: shadow });\n };\n\n const handleShadowColorChange = (color: string) => {\n setShadowColor(color);\n applyLiveChangesToExistingText({ shadowColor: color });\n };\n\n const handleApplyBackgroundChange = (apply: boolean) => {\n setApplyBackground(apply);\n applyLiveChangesToExistingText({ applyBackground: apply });\n };\n\n const handleBackgroundColorChange = (color: string) => {\n setBackgroundColor(color);\n applyLiveChangesToExistingText({ backgroundColor: color });\n };\n\n const handleBackgroundOpacityChange = (opacity: number) => {\n setBackgroundOpacity(opacity);\n applyLiveChangesToExistingText({ backgroundOpacity: opacity });\n };\n\n const handleApplyChanges = async () => {\n // For existing text elements, changes are already applied live via the handlers above.\n // The apply button is only meaningful when creating a new text element.\n if (selectedElement instanceof TextElement) {\n return;\n }\n\n const textElement = new TextElement(textContent)\n .setFontSize(fontSize)\n .setFontFamily(selectedFont)\n .setFontWeight(isBold ? 700 : 400)\n .setFontStyle(isItalic ? \"italic\" : \"normal\")\n .setFill(textColor)\n .setStrokeColor(strokeColor)\n .setLineWidth(strokeWidth)\n .setTextAlign(\"center\");\n\n const nextProps = { ...textElement.getProps() };\n if (applyShadow) {\n nextProps.shadowColor = shadowColor;\n nextProps.shadowOffset = DEFAULT_TEXT_PROPS.shadowOffset;\n nextProps.shadowBlur = DEFAULT_TEXT_PROPS.shadowBlur;\n nextProps.shadowOpacity = DEFAULT_TEXT_PROPS.shadowOpacity;\n }\n if (applyBackground) {\n nextProps.backgroundColor = backgroundColor;\n nextProps.backgroundOpacity = backgroundOpacity;\n }\n textElement.setProps(nextProps);\n await addElement(textElement);\n };\n\n useEffect(() => {\n if (selectedElement instanceof TextElement) {\n setTextContent(selectedElement.getText());\n const textProps = selectedElement.getProps();\n setSelectedFont(textProps.fontFamily ?? DEFAULT_TEXT_PROPS.fontFamily);\n setFontSize(textProps.fontSize ?? DEFAULT_TEXT_PROPS.fontSize);\n setIsBold(textProps.fontWeight === 700);\n setIsItalic(textProps.fontStyle === \"italic\");\n setTextColor(textProps.fill ?? DEFAULT_TEXT_PROPS.textColor);\n setStrokeColor(textProps.stroke ?? DEFAULT_TEXT_PROPS.strokeColor);\n setStrokeWidth(textProps.lineWidth ?? DEFAULT_TEXT_PROPS.strokeWidth);\n const hasShadow = textProps.shadowColor !== undefined;\n setApplyShadow(hasShadow);\n if (hasShadow) {\n setShadowColor(textProps.shadowColor ?? DEFAULT_TEXT_PROPS.shadowColor);\n }\n const hasBackground = textProps.backgroundColor != null && textProps.backgroundColor !== \"\";\n setApplyBackground(hasBackground);\n if (hasBackground) {\n setBackgroundColor(textProps.backgroundColor ?? \"#FACC15\");\n setBackgroundOpacity(textProps.backgroundOpacity ?? 1);\n }\n } else {\n setTextContent(DEFAULT_TEXT_PROPS.text);\n setFontSize(DEFAULT_TEXT_PROPS.fontSize);\n setSelectedFont(DEFAULT_TEXT_PROPS.fontFamily);\n setIsBold(DEFAULT_TEXT_PROPS.fontWeight === 700);\n setIsItalic(DEFAULT_TEXT_PROPS.fontStyle === \"italic\");\n setTextColor(DEFAULT_TEXT_PROPS.textColor);\n setStrokeColor(DEFAULT_TEXT_PROPS.strokeColor);\n setStrokeWidth(DEFAULT_TEXT_PROPS.strokeWidth);\n setApplyShadow(DEFAULT_TEXT_PROPS.applyShadow);\n setShadowColor(DEFAULT_TEXT_PROPS.shadowColor);\n setApplyBackground(false);\n setBackgroundColor(\"#FACC15\");\n setBackgroundOpacity(1);\n }\n }, [selectedElement]);\n\n return {\n textContent,\n fontSize,\n selectedFont,\n isBold,\n isItalic,\n textColor,\n strokeColor,\n applyShadow,\n shadowColor,\n strokeWidth,\n fonts,\n operation: selectedElement instanceof TextElement ? \"Apply Changes\": \"Add Text\",\n setTextContent: handleTextContentChange,\n setFontSize: handleFontSizeChange,\n setSelectedFont: handleSelectedFontChange,\n setIsBold: handleIsBoldChange,\n setIsItalic: handleIsItalicChange,\n setTextColor: handleTextColorChange,\n setStrokeColor: handleStrokeColorChange,\n setApplyShadow: handleApplyShadowChange,\n setShadowColor: handleShadowColorChange,\n setStrokeWidth: handleStrokeWidthChange,\n applyBackground,\n backgroundColor,\n backgroundOpacity,\n setApplyBackground: handleApplyBackgroundChange,\n setBackgroundColor: handleBackgroundColorChange,\n setBackgroundOpacity: handleBackgroundOpacityChange,\n handleApplyChanges,\n };\n};\n","import { TrackElement } from \"@twick/timeline\";\nimport { TextPanel } from \"../panel/text-panel\";\nimport { useTextPanel } from \"../../hooks/use-text-panel\";\n\ninterface TextPanelContainerProps {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}\n\nexport function TextPanelContainer(props: TextPanelContainerProps) {\n const textPanelProps = useTextPanel(props);\n return <TextPanel {...textPanelProps} />;\n}\n","import { TextElement } from \"@twick/timeline\";\nimport { AVAILABLE_TEXT_FONTS } from \"@twick/video-editor\";\n\ninterface TextStylePanelProps {\n addElement: (element: TextElement) => void;\n}\n\ninterface TextStylePreset {\n id: string;\n label: string;\n description: string;\n fontFamily: string;\n fontSize: number;\n fontWeight: number;\n textColor: string;\n strokeColor: string;\n strokeWidth: number;\n applyShadow: boolean;\n shadowColor?: string;\n applyBackground: boolean;\n backgroundColor?: string;\n backgroundOpacity?: number;\n}\n\nconst TEXT_STYLE_PRESETS: TextStylePreset[] = [\n // Utility / captions\n {\n id: \"classic-subtitle\",\n label: \"Classic Subtitle\",\n description: \"White text with subtle outline\",\n fontFamily: AVAILABLE_TEXT_FONTS.ROBOTO,\n fontSize: 32,\n fontWeight: 500,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 0.5,\n applyShadow: false,\n applyBackground: false,\n },\n {\n id: \"minimal-subtitle\",\n label: \"Minimal Subtitle\",\n description: \"Clean white text, no effects\",\n fontFamily: AVAILABLE_TEXT_FONTS.MULISH,\n fontSize: 30,\n fontWeight: 500,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: false,\n },\n {\n id: \"bold-caption\",\n label: \"Bold Caption\",\n description: \"Bold white with strong outline\",\n fontFamily: AVAILABLE_TEXT_FONTS.ROBOTO,\n fontSize: 34,\n fontWeight: 700,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 1,\n applyShadow: false,\n applyBackground: false,\n },\n {\n id: \"bar-caption\",\n label: \"Bar Caption\",\n description: \"White text on dark bar\",\n fontFamily: AVAILABLE_TEXT_FONTS.RUBIK,\n fontSize: 30,\n fontWeight: 600,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: true,\n backgroundColor: \"#020617\",\n backgroundOpacity: 0.85,\n },\n // Titles\n {\n id: \"big-title\",\n label: \"Big Title\",\n description: \"Large bold center title\",\n fontFamily: AVAILABLE_TEXT_FONTS.LUCKIEST_GUY,\n fontSize: 56,\n fontWeight: 700,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 0.5,\n applyShadow: true,\n shadowColor: \"#000000\",\n applyBackground: false,\n },\n {\n id: \"minimal-title\",\n label: \"Minimal Title\",\n description: \"Lightweight clean heading\",\n fontFamily: AVAILABLE_TEXT_FONTS.PLAYFAIR_DISPLAY,\n fontSize: 42,\n fontWeight: 400,\n textColor: \"#E5E7EB\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: false,\n },\n {\n id: \"highlight-title\",\n label: \"Highlight Title\",\n description: \"Bold on yellow highlight\",\n fontFamily: AVAILABLE_TEXT_FONTS.POPPINS,\n fontSize: 40,\n fontWeight: 700,\n textColor: \"#111827\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: true,\n backgroundColor: \"#FACC15\",\n backgroundOpacity: 0.9,\n },\n {\n id: \"outline-title\",\n label: \"Outline Title\",\n description: \"Bold outlined title\",\n fontFamily: AVAILABLE_TEXT_FONTS.KUMAR_ONE_OUTLINE,\n fontSize: 48,\n fontWeight: 700,\n textColor: \"#000000\",\n strokeColor: \"#FFFFFF\",\n strokeWidth: 1.2,\n applyShadow: false,\n applyBackground: false,\n },\n // Social / handle\n {\n id: \"handle-chip\",\n label: \"Handle Chip\",\n description: \"@handle chip style\",\n fontFamily: AVAILABLE_TEXT_FONTS.RUBIK,\n fontSize: 26,\n fontWeight: 600,\n textColor: \"#0F172A\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: true,\n backgroundColor: \"#E5E7EB\",\n backgroundOpacity: 1,\n },\n {\n id: \"cta-pill\",\n label: \"CTA Pill\",\n description: \"Call-to-action pill\",\n fontFamily: AVAILABLE_TEXT_FONTS.LUCKIEST_GUY,\n fontSize: 28,\n fontWeight: 700,\n textColor: \"#FFFFFF\",\n strokeColor: \"#000000\",\n strokeWidth: 0,\n applyShadow: false,\n applyBackground: true,\n backgroundColor: \"#22C55E\",\n backgroundOpacity: 1,\n },\n];\n\nexport function TextStylePanel({ addElement }: TextStylePanelProps) {\n const createTextFromPreset = async (preset: TextStylePreset) => {\n const textElement = new TextElement(\"Sample\")\n .setFontSize(preset.fontSize)\n .setFontFamily(preset.fontFamily)\n .setFontWeight(preset.fontWeight)\n .setFontStyle(\"normal\")\n .setFill(preset.textColor)\n .setStrokeColor(preset.strokeColor)\n .setLineWidth(preset.strokeWidth)\n .setTextAlign(\"center\");\n\n const nextProps = { ...textElement.getProps() };\n\n if (preset.applyShadow && preset.shadowColor) {\n nextProps.shadowColor = preset.shadowColor;\n nextProps.shadowOffset = [0, 0];\n nextProps.shadowBlur = 2;\n nextProps.shadowOpacity = 1;\n }\n\n if (preset.applyBackground && preset.backgroundColor) {\n nextProps.backgroundColor = preset.backgroundColor;\n nextProps.backgroundOpacity = preset.backgroundOpacity ?? 1;\n }\n\n textElement.setProps(nextProps);\n\n await addElement(textElement);\n };\n\n const handlePresetClick = (preset: TextStylePreset) => {\n void createTextFromPreset(preset);\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Text Style</div>\n <div className=\"panel-section\">\n <div className=\"text-style-grid\">\n {TEXT_STYLE_PRESETS.map((preset) => (\n <button\n key={preset.id}\n type=\"button\"\n className=\"text-style-card\"\n onClick={() => handlePresetClick(preset)}\n >\n <div className=\"text-style-preview\">\n <div\n style={{\n padding: preset.applyBackground ? \"0.35rem 0.9rem\" : 0,\n borderRadius: preset.applyBackground ? \"999px\" : 0,\n backgroundColor: preset.applyBackground\n ? preset.backgroundColor\n : \"transparent\",\n boxShadow:\n preset.applyBackground && preset.backgroundOpacity && preset.backgroundOpacity > 0.8\n ? \"0 0 20px rgba(0, 0, 0, 0.55)\"\n : undefined,\n }}\n >\n <span\n style={{\n fontFamily: preset.fontFamily,\n fontWeight: preset.fontWeight,\n // Scale preview size relative to configured size but clamp for tiles\n fontSize: Math.max(10, Math.min(18, preset.fontSize * 0.35)),\n color: preset.textColor,\n WebkitTextStroke:\n preset.strokeWidth > 0\n ? `${preset.strokeWidth}px ${preset.strokeColor}`\n : undefined,\n textShadow:\n preset.applyShadow && preset.shadowColor\n ? `0 0 16px ${preset.shadowColor}`\n : undefined,\n }}\n >\n {preset.label}\n </span>\n </div>\n </div>\n </button>\n ))}\n </div>\n </div>\n </div>\n );\n}\n\n","import type { TrackElement } from \"@twick/timeline\";\nimport { TextStylePanel } from \"../panel/text-style-panel\";\n\ninterface TextStylePanelContainerProps {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}\n\nexport function TextStylePanelContainer({ addElement }: TextStylePanelContainerProps) {\n return (\n <TextStylePanel\n addElement={addElement}\n />\n );\n}\n\n","export const BASIC_VERTEX_SHADER = `\n attribute vec2 a_position;\n attribute vec2 a_texCoord;\n varying vec2 v_texCoord;\n void main() {\n v_texCoord = a_texCoord;\n gl_Position = vec4(a_position, 0.0, 1.0);\n }\n`;\nconst SEPIA_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uIntensity;\n void main() {\n vec4 color = texture2D(uTexture, v_texCoord);\n vec3 c = color.rgb;\n vec3 sepia = vec3(\n dot(c, vec3(0.393, 0.769, 0.189)),\n dot(c, vec3(0.349, 0.686, 0.168)),\n dot(c, vec3(0.272, 0.534, 0.131))\n );\n vec3 mixed = mix(c, sepia, clamp(uIntensity, 0.0, 1.0));\n gl_FragColor = vec4(mixed, color.a);\n }\n`;\nconst VIGNETTE_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uIntensity;\n void main() {\n vec2 uv = v_texCoord - 0.5;\n float dist = length(uv);\n float vignette = smoothstep(0.8, 0.3, dist);\n vec4 color = texture2D(uTexture, v_texCoord);\n color.rgb *= mix(1.0, vignette, clamp(uIntensity, 0.0, 1.0));\n gl_FragColor = color;\n }\n`;\nconst PIXELATE_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform vec2 uResolution;\n uniform float uIntensity;\n void main() {\n float pixelSize = mix(1.0, 20.0, clamp(uIntensity, 0.0, 1.0));\n vec2 uv = v_texCoord;\n vec2 coord = floor(uv * uResolution / pixelSize) * pixelSize / uResolution;\n vec4 color = texture2D(uTexture, coord);\n gl_FragColor = color;\n }\n`;\nconst WARP_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n void main() {\n vec2 uv = v_texCoord;\n float strength = 0.03 * uIntensity;\n uv.x += sin(uv.y * 20.0 + uTime * 10.0) * strength;\n uv.y += cos(uv.x * 20.0 + uTime * 8.0) * strength;\n vec4 color = texture2D(uTexture, uv);\n gl_FragColor = color;\n }\n`;\n// Simplified from openvideo \"Glitch\" style effect: time-based slice + RGB offset.\nconst GLITCH_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(float n) { return fract(sin(n) * 43758.5453123); }\n float rand2(vec2 p) { return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); }\n\n void main(void) {\n vec2 uv = v_texCoord;\n\n // Slice count and RGB offset scale with intensity\n float sliceCount = mix(6.0, 24.0, clamp(uIntensity, 0.0, 1.0));\n float baseShift = 0.01 * clamp(uIntensity, 0.0, 1.0);\n\n float sliceId = floor(uv.y * sliceCount);\n float sliceShift = (rand(sliceId + uTime * 10.0) - 0.5) * 0.25 * baseShift;\n uv.x += sliceShift;\n\n float rShift = baseShift;\n float gShift = -baseShift * 0.5;\n float bShift = baseShift * 0.75;\n\n vec3 col;\n col.r = texture2D(uTexture, uv + vec2(rShift, 0.0)).r;\n col.g = texture2D(uTexture, uv + vec2(gShift, 0.0)).g;\n col.b = texture2D(uTexture, uv + vec2(bShift, 0.0)).b;\n\n float noise = rand2(vec2(uTime * 50.0, uv.y * 100.0));\n float noiseIntensity = noise * 0.2 * clamp(uIntensity, 0.0, 1.0);\n\n col += noiseIntensity;\n gl_FragColor = vec4(col, 1.0);\n }\n`;\n// RGB shift / chromatic aberration style effect.\nconst RGB_SHIFT_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n if (base.a < 0.01) {\n gl_FragColor = base;\n return;\n }\n\n float shiftAmount = mix(0.001, 0.02, clamp(uIntensity, 0.0, 1.0));\n float angle = 0.5 + sin(uTime * 0.7) * 0.5;\n vec2 dir = vec2(cos(angle), sin(angle));\n\n float wobble = sin(uTime * 10.0) * shiftAmount * 0.5;\n\n vec2 rUV = clamp(uv + dir * shiftAmount + vec2(wobble, 0.0), 0.0, 1.0);\n vec2 gUV = clamp(uv, 0.0, 1.0);\n vec2 bUV = clamp(uv - dir * shiftAmount - vec2(wobble, 0.0), 0.0, 1.0);\n\n float r = texture2D(uTexture, rUV).r;\n float g = texture2D(uTexture, gUV).g;\n float b = texture2D(uTexture, bUV).b;\n\n gl_FragColor = vec4(r, g, b, base.a);\n }\n`;\n// Halftone / dot pattern – intensity controls dot size and strength.\nconst HALFTONE_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float luminance(vec3 c) {\n return dot(c, vec3(0.299, 0.587, 0.114));\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n\n float angle = uTime * 0.3;\n float ca = cos(angle);\n float sa = sin(angle);\n mat2 rot = mat2(ca, -sa, sa, ca);\n vec2 rotatedUV = rot * (uv - 0.5) + 0.5;\n\n float dotSize = mix(0.06, 0.015, clamp(uIntensity, 0.0, 1.0));\n vec2 grid = rotatedUV / dotSize;\n vec2 cell = floor(grid) + 0.5;\n vec2 cellCenter = cell * dotSize;\n\n vec4 texColor = texture2D(uTexture, uv);\n float lum = luminance(texColor.rgb);\n float radius = (1.0 - lum) * dotSize * 0.5;\n\n float dist = distance(rotatedUV, cellCenter);\n float mask = smoothstep(radius, radius * 0.8, dist);\n\n vec3 halftone = texColor.rgb * mask;\n float mixAmount = clamp(uIntensity, 0.0, 1.0);\n texColor.rgb = mix(texColor.rgb, halftone, mixAmount);\n\n gl_FragColor = texColor;\n }\n`;\n// Animated hue shift; intensity controls mix amount.\nconst HUE_SHIFT_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n vec3 hueShift(vec3 color, float angle) {\n float cosA = cos(angle);\n float sinA = sin(angle);\n mat3 rot = mat3(\n 0.299 + 0.701 * cosA + 0.168 * sinA,\n 0.587 - 0.587 * cosA + 0.330 * sinA,\n 0.114 - 0.114 * cosA - 0.497 * sinA,\n\n 0.299 - 0.299 * cosA - 0.328 * sinA,\n 0.587 + 0.413 * cosA + 0.035 * sinA,\n 0.114 - 0.114 * cosA + 0.292 * sinA,\n\n 0.299 - 0.300 * cosA + 1.250 * sinA,\n 0.587 - 0.588 * cosA - 1.050 * sinA,\n 0.114 + 0.886 * cosA - 0.203 * sinA\n );\n return color * rot;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 tex = texture2D(uTexture, uv);\n float amount = clamp(uIntensity, 0.0, 1.0);\n\n vec3 shifted = hueShift(tex.rgb, uTime * 2.5);\n tex.rgb = mix(tex.rgb, shifted, amount);\n\n gl_FragColor = tex;\n }\n`;\n// Horizontal wave distortion – intensity controls strength.\nconst WAVE_DISTORT_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n void main(void) {\n vec2 uv = v_texCoord;\n float strength = mix(0.0, 0.03, clamp(uIntensity, 0.0, 1.0));\n float time = uTime * 10.0;\n float wave = sin((uv.y * 18.0) - time);\n float offsetX = wave * strength;\n vec2 distortedUV = clamp(uv + vec2(offsetX, 0.0), 0.0, 1.0);\n vec4 color = texture2D(uTexture, distortedUV);\n gl_FragColor = color;\n }\n`;\n// TV scanlines and subtle noise.\nconst TV_SCANLINES_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(vec2 p) {\n return fract(sin(dot(p ,vec2(12.9898,78.233))) * 43758.5453);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 tex = texture2D(uTexture, uv);\n vec3 base = tex.rgb;\n\n float lineThickness = mix(1.0, 3.0, clamp(uIntensity, 0.0, 1.0));\n float line = sin(uv.y * 800.0 * lineThickness) * 0.5 + 0.5;\n float lineIntensity = mix(0.2, 0.8, clamp(uIntensity, 0.0, 1.0));\n line = mix(1.0, line, lineIntensity);\n\n float noise = (rand(vec2(uTime, uv.y * 1000.0)) - 0.5) * 0.1 * clamp(uIntensity, 0.0, 1.0);\n vec3 color = base * line + noise;\n\n gl_FragColor = vec4(color, tex.a);\n }\n`;\n// Simple HDR-ish tone mapping based on exposure/contrast driven by intensity.\nconst HDR_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uIntensity;\n\n vec3 adjustContrast(vec3 color, float contrast) {\n return (color - 0.5) * contrast + 0.5;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 tex = texture2D(uTexture, uv);\n vec3 color = tex.rgb;\n\n float exposure = mix(1.0, 1.8, clamp(uIntensity, 0.0, 1.0));\n float contrast = mix(1.0, 2.0, clamp(uIntensity, 0.0, 1.0));\n\n color *= exposure;\n color = adjustContrast(color, contrast);\n color = color / (color + vec3(1.0));\n\n gl_FragColor = vec4(color, tex.a);\n }\n`;\n// Retro 70s: sepia-ish fade + grain + vignette.\nconst RETRO_70S_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float noise(vec2 p) {\n return fract(sin(dot(p, vec2(12.9898,78.233)) + uTime) * 43758.5453);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 tex = texture2D(uTexture, uv);\n vec3 color = tex.rgb;\n\n // Sepia-like fade\n vec3 sepia = vec3(\n dot(color, vec3(0.393, 0.769, 0.189)),\n dot(color, vec3(0.349, 0.686, 0.168)),\n dot(color, vec3(0.272, 0.534, 0.131))\n );\n float fade = clamp(uIntensity, 0.0, 1.0);\n vec3 faded = mix(color, sepia, mix(0.4, 0.9, fade));\n\n // Film grain\n float grainAmount = mix(0.0, 0.12, fade);\n float grain = (noise(uv * 500.0) - 0.5) * grainAmount;\n faded += grain;\n\n // Slight flicker\n float flicker = 0.97 + 0.03 * sin(uTime * 60.0);\n faded *= flicker;\n\n // Vignette\n float dist = distance(uv, vec2(0.5));\n float vignette = smoothstep(0.8, 1.0, dist);\n float vignetteStrength = mix(0.0, 1.0, fade);\n faded *= (1.0 - vignette * vignetteStrength);\n\n gl_FragColor = vec4(faded, tex.a);\n }\n`;\n// Bubble-style sparkles around the frame.\nconst BUBBLE_SPARKLES_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(vec2 co) {\n return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);\n }\n\n float softCircle(vec2 uv, vec2 c, float r) {\n float d = distance(uv, c);\n return 1.0 - smoothstep(r * 0.6, r, d);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 fg = texture2D(uTexture, uv);\n\n float bubbles = 0.0;\n float count = mix(20.0, 120.0, clamp(uIntensity, 0.0, 1.0));\n\n for (float i = 0.0; i < 200.0; i++) {\n if (i >= count) break;\n float t = uTime * 0.7 + i * 0.13;\n vec2 pos = vec2(rand(vec2(i, 1.23)), rand(vec2(i, 4.56)));\n float radius = mix(0.01, 0.03, rand(vec2(i, 9.87)));\n pos.y = fract(pos.y + t * 0.1);\n bubbles += softCircle(uv, pos, radius);\n }\n\n vec3 bubbleColor = vec3(1.0, 0.9, 0.5);\n fg.rgb += bubbleColor * bubbles * clamp(uIntensity, 0.0, 1.0);\n gl_FragColor = fg;\n }\n`;\n// Heart-shaped sparkles.\nconst HEART_SPARKLES_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(vec2 co) {\n return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);\n }\n\n float heartShape(vec2 p) {\n p = (p - 0.5) * 2.0;\n p.y = -p.y;\n p.y += 0.25;\n float x = p.x;\n float y = p.y;\n float v = pow(x*x + y*y - 1.0, 3.0) - x*x*y*y*y;\n return smoothstep(0.0, 0.02, -v);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n float hearts = 0.0;\n float count = mix(10.0, 80.0, clamp(uIntensity, 0.0, 1.0));\n\n for (float i = 0.0; i < 120.0; i++) {\n if (i >= count) break;\n vec2 pos = vec2(rand(vec2(i, 1.234)), rand(vec2(i, 5.678)));\n float size = mix(0.02, 0.05, rand(vec2(i, 9.1011)));\n float vibX = (rand(vec2(i, uTime)) - 0.5) * 0.02;\n float vibY = (rand(vec2(i + 1.0, uTime)) - 0.5) * 0.02;\n vec2 hUV = (uv - (pos + vec2(vibX, vibY))) / size + 0.5;\n float h = heartShape(hUV);\n float pulse = sin(uTime * 4.0 + i) * 0.2 + 1.0;\n hearts += h * pulse;\n }\n\n vec3 heartColor = vec3(1.0, 0.3, 0.6);\n base.rgb += heartColor * hearts * clamp(uIntensity, 0.0, 1.0);\n gl_FragColor = base;\n }\n`;\n// Butterfly-shaped sparkles.\nconst BUTTERFLY_SPARKLES_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(vec2 co) {\n return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);\n }\n\n float wing(vec2 p) {\n float d = pow(p.x, 2.0) + pow(p.y * 1.2, 2.0);\n return smoothstep(0.3, 0.0, d);\n }\n\n float butterflyShape(vec2 uv) {\n vec2 p = (uv - 0.5) * 2.0;\n float body = smoothstep(0.12, 0.05, abs(p.x)) * smoothstep(0.4, 0.0, abs(p.y));\n float wL = wing(vec2(p.x * 1.2 + 0.6, p.y));\n float wR = wing(vec2(p.x * 1.2 - 0.6, p.y));\n return clamp(wL + wR + body, 0.0, 1.0);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n float butterflies = 0.0;\n float count = mix(8.0, 40.0, clamp(uIntensity, 0.0, 1.0));\n\n for (float i = 0.0; i < 80.0; i++) {\n if (i >= count) break;\n vec2 pos = vec2(rand(vec2(i, 1.234)), rand(vec2(i, 5.678)));\n float size = mix(0.03, 0.08, rand(vec2(i, 9.1011)));\n float vibX = (rand(vec2(i, uTime)) - 0.5) * 0.02;\n float vibY = (rand(vec2(i + 1.0, uTime)) - 0.5) * 0.02;\n vec2 bUV = (uv - (pos + vec2(vibX, vibY))) / size + 0.5;\n float b = butterflyShape(bUV);\n float pulse = sin(uTime * 3.0 + i) * 0.25 + 1.0;\n butterflies += b * pulse;\n }\n\n vec3 butterflyColor = vec3(0.5, 0.6, 1.0);\n base.rgb += butterflyColor * butterflies * clamp(uIntensity, 0.0, 1.0);\n gl_FragColor = base;\n }\n`;\n// Radial lightning bolt + explosion.\nconst LIGHTNING_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec2 center = vec2(0.5, 0.5);\n float dist = distance(uv, center);\n\n float speed = 0.7;\n float progress = mod(uTime * speed, 1.0);\n float width = mix(0.01, 0.07, progress);\n float lightning = smoothstep(progress + width, progress, dist);\n float noise = sin((uv.x + uv.y) * 40.0 + uTime * 12.0) * 0.5 + 0.5;\n lightning *= noise;\n\n float explosion = smoothstep(0.85, 1.0, progress);\n float burst = explosion * smoothstep(0.25, 0.0, dist);\n\n vec3 lightningColor = vec3(1.0, 0.9, 0.6) * lightning * 2.0;\n vec3 explosionColor = vec3(1.0, 0.4, 0.2) * burst * 3.0;\n\n vec4 base = texture2D(uTexture, uv);\n vec3 mixed = base.rgb + (lightningColor + explosionColor) * clamp(uIntensity, 0.0, 1.0);\n gl_FragColor = vec4(mixed, base.a);\n }\n`;\n// Lightning veins / energy center.\nconst LIGHTNING_VEINS_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n }\n\n float noise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n float a = hash(i);\n float b = hash(i + vec2(1.0, 0.0));\n float c = hash(i + vec2(0.0, 1.0));\n float d = hash(i + vec2(1.0, 1.0));\n vec2 u = f * f * (3.0 - 2.0 * f);\n return mix(a, b, u.x) +\n (c - a) * u.y * (1.0 - u.x) +\n (d - b) * u.x * u.y;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec2 center = vec2(0.5);\n vec2 dir = uv - center;\n float dist = length(dir);\n float t = uTime * 1.5;\n\n float veinNoise = noise(dir * 6.0 + t) * 0.6 +\n noise(dir * 12.0 - t * 1.3) * 0.3;\n float warpedDist = dist + veinNoise * 0.08;\n float thickness = 0.04 + veinNoise * 0.02;\n float lightning = smoothstep(thickness, 0.0, warpedDist);\n\n float branches = smoothstep(0.02, 0.0, abs(noise(dir * 20.0 + t) - 0.5));\n lightning += branches * 0.35;\n\n float pulse = sin(uTime * 10.0) * 0.3 + 0.7;\n lightning *= pulse;\n\n vec3 veinColor = vec3(0.6, 0.85, 1.0) * lightning * 2.5 * clamp(uIntensity, 0.0, 1.0);\n vec4 base = texture2D(uTexture, uv);\n gl_FragColor = vec4(base.rgb + veinColor, base.a);\n }\n`;\n// Sparks particles.\nconst SPARKS_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n }\n\n vec3 randomColor(float h) {\n return vec3(\n 0.5 + 0.5 * sin(h * 6.2831),\n 0.5 + 0.5 * sin(h * 6.2831 + 2.1),\n 0.5 + 0.5 * sin(h * 6.2831 + 4.2)\n );\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n vec3 sparkColor = vec3(0.0);\n float sparkAlpha = 0.0;\n\n float density = mix(10.0, 40.0, clamp(uIntensity, 0.0, 1.0));\n vec2 grid = floor(uv * density);\n float h = hash(grid);\n vec2 offset = vec2(fract(h * 13.3), fract(h * 7.7 + uTime * 2.0));\n vec2 cellUV = fract(uv * density) - offset;\n float d = length(cellUV);\n\n float size = mix(0.1, 0.25, clamp(uIntensity, 0.0, 1.0));\n float spark = smoothstep(size, 0.0, d);\n vec3 color = randomColor(h) * spark;\n sparkColor += color;\n sparkAlpha += spark;\n\n vec3 finalColor = base.rgb + sparkColor;\n gl_FragColor = vec4(finalColor, max(base.a, sparkAlpha));\n }\n`;\n// Horizontal laser beam across the frame.\nconst LASER_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float noise(float x) {\n return sin(x * 40.0) * 0.005;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 baseColor = texture2D(uTexture, uv);\n\n float beamY = 0.5 + noise(uv.x + uTime * 5.0);\n float thickness = mix(0.01, 0.04, clamp(uIntensity, 0.0, 1.0));\n float dist = abs(uv.y - beamY);\n\n float core = smoothstep(thickness, 0.0, dist);\n float glow = smoothstep(thickness * 4.0, thickness, dist);\n float pulse = 0.6 + 0.4 * sin(uTime * 10.0);\n float laserMask = (core + glow * 1.5) * pulse * clamp(uIntensity, 0.0, 1.0);\n\n vec3 laserColor = vec3(1.0, 0.1, 0.3) * laserMask;\n vec3 color = baseColor.rgb + laserColor;\n gl_FragColor = vec4(color, baseColor.a);\n }\n`;\n// Water reflection in lower half of frame.\nconst WATER_REFLECTION_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n void main(void) {\n vec2 uv = v_texCoord;\n\n if (uv.y < 0.5) {\n gl_FragColor = texture2D(uTexture, uv);\n return;\n }\n\n vec2 reflectUV = uv;\n reflectUV.y = 1.0 - uv.y;\n float wave =\n sin(reflectUV.y * 30.0 + uTime * 2.5) *\n mix(0.0, 0.03, clamp(uIntensity, 0.0, 1.0));\n reflectUV.x += wave;\n reflectUV = clamp(reflectUV, 0.0, 1.0);\n vec4 reflectColor = texture2D(uTexture, reflectUV);\n float fade = smoothstep(0.5, 1.0, uv.y);\n reflectColor.rgb *= (1.0 - fade) * 0.9;\n reflectColor.a *= (1.0 - fade);\n gl_FragColor = reflectColor;\n }\n`;\n// Bouncing balls overlay.\nconst BOUNCING_BALLS_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n const int BALL_COUNT = 10;\n\n vec2 bounce(vec2 p) {\n return abs(fract(p) * 2.0 - 1.0);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 color = texture2D(uTexture, uv);\n\n float radius = mix(0.03, 0.07, clamp(uIntensity, 0.0, 1.0));\n float border = radius * 0.25;\n float ballsAlpha = 0.0;\n\n for (int i = 0; i < BALL_COUNT; i++) {\n float id = float(i) + 1.0;\n vec2 speed = vec2(0.3 + id * 0.12, 0.25 + id * 0.15);\n vec2 pos = bounce(vec2(uTime * speed.x + id * 0.17, uTime * speed.y + id * 0.29));\n float d = distance(uv, pos);\n float edge = smoothstep(radius, radius - border, d) -\n smoothstep(radius - border, radius - border - 0.01, d);\n ballsAlpha += edge;\n }\n\n ballsAlpha = clamp(ballsAlpha, 0.0, 1.0) * clamp(uIntensity, 0.0, 1.0);\n color.rgb = mix(color.rgb, vec3(1.0), ballsAlpha);\n gl_FragColor = color;\n }\n`;\n// Paper break / tear reveal style effect.\nconst PAPER_BREAK_REVEAL_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float noise(float x) {\n return sin(x * 28.0) * 0.035;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n\n float t = clamp(uTime, 0.0, 1.0);\n float cutCenter = 0.5;\n float wiggle = noise(uv.y + uTime * 3.0) * 0.2 * t;\n float tearLine = cutCenter + wiggle * clamp(uIntensity, 0.0, 1.0);\n\n float split = 0.3 * t * clamp(uIntensity, 0.0, 1.0);\n vec2 leftUV = uv;\n vec2 rightUV = uv;\n leftUV.x -= split * step(uv.x, tearLine);\n rightUV.x += split * step(tearLine, uv.x);\n leftUV = clamp(leftUV, 0.0, 1.0);\n rightUV = clamp(rightUV, 0.0, 1.0);\n\n vec4 left = texture2D(uTexture, leftUV);\n vec4 right = texture2D(uTexture, rightUV);\n float cutMask = smoothstep(tearLine - 0.02, tearLine + 0.02, uv.x);\n vec4 broken = mix(left, right, cutMask);\n\n float edge = smoothstep(0.0, 0.02, abs(uv.x - tearLine)) *\n (1.0 - smoothstep(0.02, 0.05, abs(uv.x - tearLine)));\n vec3 edgeColor = vec3(1.0) * edge * t;\n broken.rgb += edgeColor;\n\n gl_FragColor = mix(base, broken, t);\n }\n`;\n// Camera shake / move.\nconst CAMERA_MOVE_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(float x) {\n return fract(sin(x * 12.9898) * 43758.5453);\n }\n\n vec2 shakeOffset(float time, float intensity) {\n float x = (rand(time * 0.7) - 0.5) * intensity;\n float y = (rand(time * 1.3 + 10.0) - 0.5) * intensity;\n return vec2(x, y);\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n float intensity = mix(0.0, 0.04, clamp(uIntensity, 0.0, 1.0));\n vec2 offset = shakeOffset(uTime * 2.0, intensity);\n vec2 uvMoved = clamp(uv + offset, 0.0, 1.0);\n vec4 color = texture2D(uTexture, uvMoved);\n gl_FragColor = color;\n }\n`;\n// Black flash pulses.\nconst BLACK_FLASH_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n float duration = 0.3;\n float m = mod(uTime, duration);\n float flash = smoothstep(0.0, duration * 0.5, m) *\n (1.0 - smoothstep(duration * 0.5, duration, m));\n flash *= clamp(uIntensity, 0.0, 1.0);\n vec3 color = mix(base.rgb, vec3(0.0), flash);\n gl_FragColor = vec4(color, base.a);\n }\n`;\n// Bright pulse + slight blur.\nconst BRIGHT_PULSE_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n vec4 blur3(sampler2D tex, vec2 uv, vec2 texel) {\n vec4 c = vec4(0.0);\n c += texture2D(tex, uv + texel * vec2(-1.0, -1.0)) * 0.0625;\n c += texture2D(tex, uv + texel * vec2( 0.0, -1.0)) * 0.125;\n c += texture2D(tex, uv + texel * vec2( 1.0, -1.0)) * 0.0625;\n c += texture2D(tex, uv + texel * vec2(-1.0, 0.0)) * 0.125;\n c += texture2D(tex, uv) * 0.25;\n c += texture2D(tex, uv + texel * vec2( 1.0, 0.0)) * 0.125;\n c += texture2D(tex, uv + texel * vec2(-1.0, 1.0)) * 0.0625;\n c += texture2D(tex, uv + texel * vec2( 0.0, 1.0)) * 0.125;\n c += texture2D(tex, uv + texel * vec2( 1.0, 1.0)) * 0.0625;\n return c;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec2 texel = vec2(1.0 / 1024.0);\n float pulse = 0.5 + 0.5 * sin(uTime * 3.0);\n float scale = 1.0 + pulse * 0.3 * clamp(uIntensity, 0.0, 1.0);\n vec2 center = vec2(0.5, 0.5);\n vec2 uvScaled = (uv - center) / scale + center;\n uvScaled = clamp(uvScaled, 0.0, 1.0);\n vec4 base = texture2D(uTexture, uvScaled);\n vec4 blurred = blur3(uTexture, uvScaled, texel * 1.5);\n vec4 colorValue = mix(base, blurred, 0.7 * clamp(uIntensity, 0.0, 1.0));\n gl_FragColor = colorValue;\n }\n`;\n// Random accent blobs with two colors.\nconst RANDOM_ACCENTS_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n }\n\n vec3 accentColor(float h) {\n vec3 colorA = vec3(1.0, 0.2, 0.6);\n vec3 colorB = vec3(0.2, 0.8, 1.0);\n return mix(colorA, colorB, fract(h * 7.0));\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n float density = mix(10.0, 25.0, clamp(uIntensity, 0.0, 1.0));\n vec2 gridUV = floor(uv * density);\n float h = hash(gridUV);\n\n vec2 offset = vec2(fract(h * 13.3), fract(h * 7.7));\n vec2 accentUV = fract(uv * density) - offset;\n float dist = length(accentUV);\n float size = mix(0.2, 0.08, clamp(uIntensity, 0.0, 1.0));\n float accent = smoothstep(size, 0.0, dist);\n accent *= 0.6 + 0.4 * sin(uTime * 10.0 + h * 6.2831);\n vec3 color = accentColor(h) * accent * clamp(uIntensity, 0.0, 1.0);\n float alpha = accent;\n gl_FragColor = vec4(color + base.rgb, max(base.a, alpha));\n }\n`;\n// Graffiti spray + drips over the frame.\nconst GRAFFITI_FRAGMENT = /* glsl */ `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D uTexture;\n uniform float uTime;\n uniform float uIntensity;\n\n float rand(vec2 st) {\n return fract(sin(dot(st, vec2(12.9898,78.233))) * 43758.5453123);\n }\n\n float noise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = rand(i);\n float b = rand(i + vec2(1.0, 0.0));\n float c = rand(i + vec2(0.0, 1.0));\n float d = rand(i + vec2(1.0, 1.0));\n vec2 u = f * f * (3.0 - 2.0 * f);\n return mix(a, b, u.x) +\n (c - a) * u.y * (1.0 - u.x) +\n (d - b) * u.x * u.y;\n }\n\n float spray(vec2 st, float radius) {\n float dist = length(st - vec2(0.28, 0.5));\n float base = smoothstep(radius, radius - 0.06, dist);\n float speckle =\n noise(st * 45.0 + uTime * 3.0) *\n noise(st * 90.0);\n return clamp(base + speckle * 0.7, 0.0, 1.0);\n }\n\n float drips(vec2 st, float mask) {\n float column = noise(vec2(st.x * 25.0, 0.0));\n float drip =\n smoothstep(0.3, 0.7, column) *\n smoothstep(0.1, 1.0, 1.0 - st.y);\n float flow =\n noise(vec2(st.x * 35.0, st.y * 6.0 + uTime * 2.5));\n return drip * flow * mask;\n }\n\n void main(void) {\n vec2 uv = v_texCoord;\n vec4 base = texture2D(uTexture, uv);\n vec3 graffitiColor = vec3(1.0, 0.0, 0.5);\n float reveal = clamp(uIntensity, 0.0, 1.0);\n float sprayMask = spray(uv, 0.35 * reveal);\n float dripMask = drips(uv, sprayMask) * reveal;\n float graffitiMask = clamp(sprayMask + dripMask * 1.3, 0.0, 1.0);\n vec3 graffiti = graffitiColor * graffitiMask;\n vec3 Color = base.rgb + graffiti;\n gl_FragColor = vec4(Color, base.a);\n }\n`;\nexport const EFFECTS = {\n sepia: {\n key: \"sepia\",\n label: \"Sepia\",\n description: \"Warm vintage sepia tone.\",\n fragment: SEPIA_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n vignette: {\n key: \"vignette\",\n label: \"Vignette\",\n description: \"Darken edges to focus center.\",\n fragment: VIGNETTE_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n pixelate: {\n key: \"pixelate\",\n label: \"Pixelate\",\n description: \"Blocky pixelation effect.\",\n fragment: PIXELATE_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n warp: {\n key: \"warp\",\n label: \"Warp\",\n description: \"Sinusoidal warp of the frame.\",\n fragment: WARP_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n glitch: {\n key: \"glitch\",\n label: \"Glitch\",\n description: \"RGB slice and noise glitch.\",\n fragment: GLITCH_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.6 } },\n },\n rgbShift: {\n key: \"rgbShift\",\n label: \"RGB Shift\",\n description: \"Chromatic aberration style RGB split.\",\n fragment: RGB_SHIFT_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n halftone: {\n key: \"halftone\",\n label: \"Halftone\",\n description: \"Animated halftone dot shading.\",\n fragment: HALFTONE_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n hueShift: {\n key: \"hueShift\",\n label: \"Hue Shift\",\n description: \"Animated hue rotation of colors.\",\n fragment: HUE_SHIFT_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n waveDistort: {\n key: \"waveDistort\",\n label: \"Wave Distort\",\n description: \"Horizontal wave distortion.\",\n fragment: WAVE_DISTORT_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n tvScanlines: {\n key: \"tvScanlines\",\n label: \"TV Scanlines\",\n description: \"Old TV scanlines with subtle noise.\",\n fragment: TV_SCANLINES_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n hdr: {\n key: \"hdr\",\n label: \"HDR Boost\",\n description: \"Exposure and contrast HDR-style boost.\",\n fragment: HDR_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n retro70s: {\n key: \"retro70s\",\n label: \"Retro 70s\",\n description: \"Grainy, faded, vignetted retro film look.\",\n fragment: RETRO_70S_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n bubbleSparkles: {\n key: \"bubbleSparkles\",\n label: \"Bubble Sparkles\",\n description: \"Floating bubble-like sparkles.\",\n fragment: BUBBLE_SPARKLES_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n heartSparkles: {\n key: \"heartSparkles\",\n label: \"Heart Sparkles\",\n description: \"Animated heart-shaped sparkles.\",\n fragment: HEART_SPARKLES_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.9 } },\n },\n butterflySparkles: {\n key: \"butterflySparkles\",\n label: \"Butterfly Sparkles\",\n description: \"Animated butterfly-shaped sparkles.\",\n fragment: BUTTERFLY_SPARKLES_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.9 } },\n },\n lightning: {\n key: \"lightning\",\n label: \"Lightning\",\n description: \"Radial lightning strike with flash.\",\n fragment: LIGHTNING_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n lightningVeins: {\n key: \"lightningVeins\",\n label: \"Lightning Veins\",\n description: \"Energy veins radiating from center.\",\n fragment: LIGHTNING_VEINS_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n sparks: {\n key: \"sparks\",\n label: \"Sparks\",\n description: \"Random colored sparks overlay.\",\n fragment: SPARKS_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.9 } },\n },\n laser: {\n key: \"laser\",\n label: \"Laser\",\n description: \"Horizontal laser beam across the frame.\",\n fragment: LASER_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n waterReflection: {\n key: \"waterReflection\",\n label: \"Water Reflection\",\n description: \"Water reflection in the lower half of the frame.\",\n fragment: WATER_REFLECTION_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n bouncingBalls: {\n key: \"bouncingBalls\",\n label: \"Bouncing Balls\",\n description: \"Bouncing light balls over the frame.\",\n fragment: BOUNCING_BALLS_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n paperBreakReveal: {\n key: \"paperBreakReveal\",\n label: \"Paper Break Reveal\",\n description: \"Tearing paper style reveal.\",\n fragment: PAPER_BREAK_REVEAL_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n cameraMove: {\n key: \"cameraMove\",\n label: \"Camera Move\",\n description: \"Camera shake / movement effect.\",\n fragment: CAMERA_MOVE_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n blackFlash: {\n key: \"blackFlash\",\n label: \"Black Flash\",\n description: \"Periodic flash to black.\",\n fragment: BLACK_FLASH_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.7 } },\n },\n brightPulse: {\n key: \"brightPulse\",\n label: \"Bright Pulse\",\n description: \"Bright pulse with subtle blur.\",\n fragment: BRIGHT_PULSE_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n randomAccents: {\n key: \"randomAccents\",\n label: \"Random Accents\",\n description: \"Random colored accent blobs.\",\n fragment: RANDOM_ACCENTS_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 0.8 } },\n },\n graffiti: {\n key: \"graffiti\",\n label: \"Graffiti\",\n description: \"Graffiti spray paint and drips.\",\n fragment: GRAFFITI_FRAGMENT,\n defaultUniforms: { uIntensity: { type: \"float\", value: 1.0 } },\n },\n};\nexport function getEffectFragment(key) {\n if (key in EFFECTS)\n return EFFECTS[key].fragment;\n return undefined;\n}\nexport const EFFECT_OPTIONS = Object.values(EFFECTS).map((cfg) => ({\n key: cfg.key,\n label: cfg.label,\n description: cfg.description,\n}));\n//# sourceMappingURL=catalog.js.map","import { useMemo } from \"react\";\nimport { EffectElement, TrackElement, TIMELINE_ELEMENT_TYPE } from \"@twick/timeline\";\nimport type { EffectKey } from \"@twick/effects\";\n\nexport interface UseEffectPanelParams {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}\n\nexport interface UseEffectPanelResult {\n selectedEffectKey: EffectKey | null;\n handleAddEffect: (key: EffectKey) => void;\n handleUpdateEffect: (key: EffectKey) => void;\n}\n\nexport const useEffectPanel = ({\n selectedElement,\n addElement,\n updateElement,\n}: UseEffectPanelParams): UseEffectPanelResult => {\n const selectedEffectKey = useMemo<EffectKey | null>(() => {\n if (!selectedElement) return null;\n if (selectedElement.getType() !== TIMELINE_ELEMENT_TYPE.EFFECT) return null;\n const effectElement = selectedElement as unknown as EffectElement;\n const props = effectElement.getProps?.();\n const key = props?.effectKey as EffectKey | undefined;\n return key ?? null;\n }, [selectedElement]);\n\n const handleAddEffect = (key: EffectKey) => {\n const effect = new EffectElement(key);\n addElement(effect);\n };\n\n const handleUpdateEffect = (key: EffectKey) => {\n if (!selectedElement) return;\n if (selectedElement.getType() !== TIMELINE_ELEMENT_TYPE.EFFECT) return;\n const effectElement = selectedElement as unknown as EffectElement;\n effectElement.setEffectKey(key);\n updateElement(effectElement);\n };\n\n return {\n selectedEffectKey,\n handleAddEffect,\n handleUpdateEffect,\n };\n};\n\n","import { BASIC_VERTEX_SHADER, EFFECTS } from \"@twick/effects\";\nimport type { EffectKey } from \"@twick/effects\";\n\n/**\n * Lightweight singleton that renders effect previews into a single hidden\n * WebGL canvas and returns data URLs for use in <img> tags.\n *\n * This avoids creating one WebGL context per effect card and stays within\n * browser context limits.\n */\n\nlet canvas: HTMLCanvasElement | null = null;\nlet gl: WebGLRenderingContext | null = null;\n\nconst PREVIEW_WIDTH = 160;\nconst PREVIEW_HEIGHT = 90;\n\nconst cache = new Map<EffectKey, string>();\nconst pending = new Map<EffectKey, Promise<string>>();\n\nfunction ensureContext(): WebGLRenderingContext | null {\n if (typeof window === \"undefined\") return null;\n\n if (gl && canvas) {\n return gl;\n }\n\n canvas = document.createElement(\"canvas\");\n canvas.width = PREVIEW_WIDTH;\n canvas.height = PREVIEW_HEIGHT;\n canvas.style.position = \"absolute\";\n canvas.style.left = \"-9999px\";\n canvas.style.top = \"-9999px\";\n canvas.style.width = `${PREVIEW_WIDTH}px`;\n canvas.style.height = `${PREVIEW_HEIGHT}px`;\n canvas.style.pointerEvents = \"none\";\n canvas.style.opacity = \"0\";\n\n document.body.appendChild(canvas);\n\n gl =\n (canvas.getContext(\"webgl\", {\n preserveDrawingBuffer: true,\n }) as WebGLRenderingContext | null) ||\n (canvas.getContext(\"experimental-webgl\", {\n preserveDrawingBuffer: true,\n }) as WebGLRenderingContext | null);\n\n if (!gl) {\n // Cleanup if WebGL is unavailable\n canvas.remove();\n canvas = null;\n return null;\n }\n\n return gl;\n}\n\nfunction createShader(\n gl: WebGLRenderingContext,\n type: number,\n source: string,\n): WebGLShader | null {\n const shader = gl.createShader(type);\n if (!shader) return null;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n const ok = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n if (!ok) {\n gl.deleteShader(shader);\n return null;\n }\n\n return shader;\n}\n\nasync function renderEffectToDataUrl(effectKey: EffectKey): Promise<string> {\n const glCtx = ensureContext();\n if (!glCtx || !canvas) {\n return \"\";\n }\n\n const effect = EFFECTS[effectKey];\n if (!effect) return \"\";\n\n const vertexShader = createShader(glCtx, glCtx.VERTEX_SHADER, BASIC_VERTEX_SHADER);\n const fragmentShader = createShader(glCtx, glCtx.FRAGMENT_SHADER, effect.fragment);\n if (!vertexShader || !fragmentShader) {\n return \"\";\n }\n\n const program = glCtx.createProgram();\n if (!program) {\n glCtx.deleteShader(vertexShader);\n glCtx.deleteShader(fragmentShader);\n return \"\";\n }\n\n glCtx.attachShader(program, vertexShader);\n glCtx.attachShader(program, fragmentShader);\n glCtx.linkProgram(program);\n\n const linked = glCtx.getProgramParameter(program, glCtx.LINK_STATUS);\n if (!linked) {\n glCtx.deleteProgram(program);\n glCtx.deleteShader(vertexShader);\n glCtx.deleteShader(fragmentShader);\n return \"\";\n }\n\n glCtx.useProgram(program);\n\n const positionLocation = glCtx.getAttribLocation(program, \"a_position\");\n const texCoordLocation = glCtx.getAttribLocation(program, \"a_texCoord\");\n\n const positionBuffer = glCtx.createBuffer();\n glCtx.bindBuffer(glCtx.ARRAY_BUFFER, positionBuffer);\n const positions = new Float32Array([\n -1, -1,\n 1, -1,\n -1, 1,\n -1, 1,\n 1, -1,\n 1, 1,\n ]);\n glCtx.bufferData(glCtx.ARRAY_BUFFER, positions, glCtx.STATIC_DRAW);\n\n glCtx.enableVertexAttribArray(positionLocation);\n glCtx.vertexAttribPointer(positionLocation, 2, glCtx.FLOAT, false, 0, 0);\n\n const texCoordBuffer = glCtx.createBuffer();\n glCtx.bindBuffer(glCtx.ARRAY_BUFFER, texCoordBuffer);\n const texCoords = new Float32Array([\n 0, 0,\n 1, 0,\n 0, 1,\n 0, 1,\n 1, 0,\n 1, 1,\n ]);\n glCtx.bufferData(glCtx.ARRAY_BUFFER, texCoords, glCtx.STATIC_DRAW);\n\n glCtx.enableVertexAttribArray(texCoordLocation);\n glCtx.vertexAttribPointer(texCoordLocation, 2, glCtx.FLOAT, false, 0, 0);\n\n const texture = glCtx.createTexture();\n glCtx.bindTexture(glCtx.TEXTURE_2D, texture);\n const size = 64;\n const data = new Uint8Array(size * size * 4);\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n const i = (y * size + x) * 4;\n const fx = x / (size - 1);\n const fy = y / (size - 1);\n data[i + 0] = fx * 255;\n data[i + 1] = fy * 255;\n data[i + 2] = 200;\n data[i + 3] = 255;\n }\n }\n glCtx.texImage2D(\n glCtx.TEXTURE_2D,\n 0,\n glCtx.RGBA,\n size,\n size,\n 0,\n glCtx.RGBA,\n glCtx.UNSIGNED_BYTE,\n data,\n );\n glCtx.texParameteri(glCtx.TEXTURE_2D, glCtx.TEXTURE_MIN_FILTER, glCtx.LINEAR);\n glCtx.texParameteri(glCtx.TEXTURE_2D, glCtx.TEXTURE_MAG_FILTER, glCtx.LINEAR);\n glCtx.texParameteri(glCtx.TEXTURE_2D, glCtx.TEXTURE_WRAP_S, glCtx.CLAMP_TO_EDGE);\n glCtx.texParameteri(glCtx.TEXTURE_2D, glCtx.TEXTURE_WRAP_T, glCtx.CLAMP_TO_EDGE);\n\n const textureLocation = glCtx.getUniformLocation(program, \"uTexture\");\n if (textureLocation) {\n glCtx.uniform1i(textureLocation, 0);\n }\n\n const timeLocation = glCtx.getUniformLocation(program, \"uTime\");\n if (timeLocation) {\n glCtx.uniform1f(timeLocation, 1.0);\n }\n\n const intensityLocation = glCtx.getUniformLocation(program, \"uIntensity\");\n if (intensityLocation) {\n glCtx.uniform1f(intensityLocation, 0.9);\n }\n\n const resolutionLocation = glCtx.getUniformLocation(program, \"uResolution\");\n if (resolutionLocation) {\n glCtx.uniform2f(resolutionLocation, canvas.width, canvas.height);\n }\n\n glCtx.viewport(0, 0, canvas.width, canvas.height);\n glCtx.clearColor(0, 0, 0, 1);\n glCtx.clear(glCtx.COLOR_BUFFER_BIT);\n glCtx.drawArrays(glCtx.TRIANGLES, 0, 6);\n\n const url = canvas.toDataURL(\"image/png\");\n\n // Clean up per-render resources, keep context and canvas\n glCtx.deleteTexture(texture);\n glCtx.deleteBuffer(positionBuffer);\n glCtx.deleteBuffer(texCoordBuffer);\n glCtx.deleteProgram(program);\n glCtx.deleteShader(vertexShader);\n glCtx.deleteShader(fragmentShader);\n\n return url;\n}\n\nexport function getEffectPreviewForEffect(\n effectKey: EffectKey,\n): Promise<string> {\n if (cache.has(effectKey)) {\n return Promise.resolve(cache.get(effectKey) as string);\n }\n\n if (pending.has(effectKey)) {\n return pending.get(effectKey) as Promise<string>;\n }\n\n const promise = (async () => {\n const url = await renderEffectToDataUrl(effectKey);\n if (url) {\n cache.set(effectKey, url);\n }\n pending.delete(effectKey);\n return url;\n })();\n\n pending.set(effectKey, promise);\n return promise;\n}\n\n","import type { TrackElement } from \"@twick/timeline\";\nimport { EFFECT_OPTIONS } from \"@twick/effects\";\nimport type { EffectKey } from \"@twick/effects\";\nimport { useEffect, useState } from \"react\";\nimport { useEffectPanel } from \"../../hooks/use-effect-panel\";\nimport { getEffectPreviewForEffect } from \"../../helpers/effect-preview-manager\";\n\ninterface EffectStylePanelProps {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}\n\ninterface EffectPreviewProps {\n effectKey: EffectKey;\n label: string;\n}\n\nfunction EffectPreview({ effectKey, label }: EffectPreviewProps) {\n const [src, setSrc] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n getEffectPreviewForEffect(effectKey).then((url) => {\n if (!cancelled && url) {\n setSrc(url);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [effectKey]);\n\n if (!src) {\n return (\n <div className=\"effect-preview-box-inner flex items-center justify-center text-xs text-neutral-400\">\n {label}\n </div>\n );\n }\n\n return (\n <img\n src={src}\n alt={label}\n className=\"effect-preview-box-inner object-cover\"\n loading=\"lazy\"\n />\n );\n}\n\nexport function EffectStylePanel({\n selectedElement,\n addElement,\n updateElement,\n}: EffectStylePanelProps) {\n const { selectedEffectKey, handleAddEffect, handleUpdateEffect } =\n useEffectPanel({\n selectedElement,\n addElement,\n updateElement,\n });\n\n const handleClick = (key: EffectKey) => {\n if (selectedEffectKey) {\n handleUpdateEffect(key);\n } else {\n handleAddEffect(key);\n }\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Effect Style</div>\n <div className=\"panel-section\">\n <div className=\"effect-grid\">\n {EFFECT_OPTIONS.map((effect) => {\n const isSelected = effect.key === selectedEffectKey;\n return (\n <button\n key={effect.key}\n type=\"button\"\n className={`effect-preview-card${isSelected ? \" effect-preview-card-selected\" : \"\"}`}\n onClick={() => handleClick(effect.key)}\n >\n <div className=\"effect-preview-box\">\n <EffectPreview effectKey={effect.key} label={effect.label} />\n <div className=\"effect-preview-label\">{effect.label}</div>\n </div>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n );\n}\n\n","import type { TrackElement } from \"@twick/timeline\";\nimport { EffectStylePanel } from \"../panel/effect-style-panel\";\n\ninterface EffectStylePanelContainerProps {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}\n\nexport function EffectStylePanelContainer({\n selectedElement,\n addElement,\n updateElement,\n}: EffectStylePanelContainerProps) {\n return (\n <EffectStylePanel\n selectedElement={selectedElement}\n addElement={addElement}\n updateElement={updateElement}\n />\n );\n}\n\n","/**\n * CaptionsPanel Component\n *\n * A presentational panel for managing caption entries in the studio.\n * Renders a list of caption items, each with a text input and two actions:\n * Split and Delete. A single Add button appears below the list.\n *\n * State is controlled by the parent via props; this component is stateless.\n *\n * Entry shape (CaptionEntry):\n * - `s`: start time (seconds)\n * - `e`: end time (seconds)\n * - `t`: caption text\n *\n * Props:\n * - `captions`: CaptionEntry[] — ordered list of captions\n * - `addCaption()`: add a new caption at the end\n * - `splitCaption(index)`: split the caption at `index`\n * - `deleteCaption(index)`: remove the caption at `index`\n * - `updateCaption(index, caption)`: update the caption at `index`\n *\n * @component\n * @example\n * ```tsx\n * <CaptionsPanel\n * captions={captions}\n * addCaption={addCaption}\n * splitCaption={splitCaption}\n * deleteCaption={deleteCaption}\n * updateCaption={updateCaption}\n * />\n * ```\n */\n\nimport { Trash2, Scissors } from \"lucide-react\";\n\ninterface CaptionEntry {\n s: number;\n e: number;\n t: string;\n}\n\nconst formatTime = (seconds: number) => {\n if (!Number.isFinite(seconds) || seconds < 0) return \"0:00.00\";\n const totalMs = Math.round(seconds * 1000);\n const totalSeconds = Math.floor(totalMs / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const secs = totalSeconds % 60;\n const ms = Math.floor((totalMs % 1000) / 10);\n const pad = (n: number, l = 2) => String(n).padStart(l, \"0\");\n return `${minutes}:${pad(secs)}.${pad(ms)}`;\n};\n\nexport function CaptionsPanel({\n captions,\n addCaption,\n splitCaption,\n deleteCaption,\n updateCaption,\n}: {\n captions: CaptionEntry[];\n addCaption: () => void;\n splitCaption: (index: number) => void;\n deleteCaption: (index: number) => void;\n updateCaption: (index: number, caption: CaptionEntry) => void;\n}) {\n return (\n <div className=\"panel-container captions-panel\">\n {/* Header */}\n <div className=\"captions-panel-header\">\n <h3 className=\"panel-title\">Captions</h3>\n <div className=\"captions-panel-header-meta\">\n {captions.length === 0 ? (\n <span className=\"captions-panel-count\">No captions yet</span>\n ) : null}\n <button\n onClick={addCaption}\n className=\"btn-primary captions-panel-add-button\"\n title=\"Add caption\"\n >\n Add caption\n </button>\n </div>\n </div>\n\n {/* Caption list */}\n {captions.length === 0 ? (\n <div className=\"panel-section captions-panel-empty\">\n <p className=\"captions-panel-empty-title\">Start your first caption</p>\n <p className=\"captions-panel-empty-subtitle\">\n Use the button above to add the first caption block for the active track.\n </p>\n <button\n onClick={addCaption}\n className=\"btn-primary captions-panel-empty-button\"\n title=\"Add first caption\"\n >\n Add caption\n </button>\n </div>\n ) : (\n <div className=\"panel-section captions-panel-list\">\n {captions.map((caption, i) => {\n return (\n <div\n key={i}\n className=\"captions-panel-item\"\n >\n <div className=\"captions-panel-item-header\">\n <span className=\"captions-panel-time captions-panel-time-start\">\n {formatTime(caption.s)}\n </span>\n <span className=\"captions-panel-time captions-panel-time-end\">\n {formatTime(caption.e)}\n </span>\n </div>\n\n <div className=\"captions-panel-item-body\">\n <textarea\n placeholder=\"Enter caption text\"\n value={caption.t}\n onChange={(e) =>\n updateCaption(i, { ...caption, t: e.target.value })\n }\n className=\"input-dark captions-panel-textarea\"\n />\n <div className=\"captions-panel-actions\">\n <button\n onClick={() => splitCaption(i)}\n className=\"btn-ghost captions-panel-action-button\"\n title=\"Split caption at midpoint\"\n >\n <Scissors className=\"icon-sm\" />\n </button>\n <button\n onClick={() => deleteCaption(i)}\n className=\"btn-ghost captions-panel-action-button\"\n title=\"Delete caption\"\n >\n <Trash2\n className=\"icon-sm\"\n color=\"var(--color-red-500)\"\n />\n </button>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","import { CAPTION_STYLE, computeCaptionGeometry } from \"@twick/timeline\";\n\nconst HIGHLIGHT_BG_FONT_SIZE = 46;\nconst WORD_BY_WORD_FONT_SIZE = 46;\nconst WORD_BY_WORD_WITH_BG_FONT_SIZE = 46;\nconst OUTLINE_ONLY_FONT_SIZE = 42;\nconst SOFT_BOX_FONT_SIZE = 40;\n\nconst HIGHLIGHT_BG_GEOMETRY = computeCaptionGeometry(HIGHLIGHT_BG_FONT_SIZE, CAPTION_STYLE.WORD_BG_HIGHLIGHT);\nconst WORD_BY_WORD_GEOMETRY = computeCaptionGeometry(WORD_BY_WORD_FONT_SIZE, CAPTION_STYLE.WORD_BY_WORD);\nconst WORD_BY_WORD_WITH_BG_GEOMETRY = computeCaptionGeometry(WORD_BY_WORD_WITH_BG_FONT_SIZE, CAPTION_STYLE.WORD_BY_WORD_WITH_BG);\nconst OUTLINE_ONLY_GEOMETRY = computeCaptionGeometry(OUTLINE_ONLY_FONT_SIZE, CAPTION_STYLE.OUTLINE_ONLY);\nconst SOFT_BOX_GEOMETRY = computeCaptionGeometry(SOFT_BOX_FONT_SIZE, CAPTION_STYLE.SOFT_BOX);\n\nexport const CAPTION_PROPS = {\n [CAPTION_STYLE.WORD_BG_HIGHLIGHT]: {\n font: {\n size: HIGHLIGHT_BG_FONT_SIZE,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n },\n lineWidth: HIGHLIGHT_BG_GEOMETRY.lineWidth,\n rectProps: HIGHLIGHT_BG_GEOMETRY.rectProps,\n stroke: \"#000000\",\n fontWeight: 700,\n shadowOffset: [-1, 1],\n shadowColor: \"#000000\",\n },\n [CAPTION_STYLE.WORD_BY_WORD]: {\n font: {\n size: WORD_BY_WORD_FONT_SIZE,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n }, \n lineWidth: WORD_BY_WORD_GEOMETRY.lineWidth,\n rectProps: WORD_BY_WORD_GEOMETRY.rectProps,\n stroke: \"#000000\",\n shadowOffset: [-1, 1],\n shadowColor: \"#000000\",\n shadowBlur: 5,\n },\n [CAPTION_STYLE.WORD_BY_WORD_WITH_BG]: {\n font: {\n size: WORD_BY_WORD_WITH_BG_FONT_SIZE,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n },\n lineWidth: WORD_BY_WORD_WITH_BG_GEOMETRY.lineWidth,\n rectProps: WORD_BY_WORD_WITH_BG_GEOMETRY.rectProps,\n shadowOffset: [-1, 1],\n shadowColor: \"#000000\",\n shadowBlur: 5,\n },\n [CAPTION_STYLE.OUTLINE_ONLY]: {\n font: {\n size: OUTLINE_ONLY_FONT_SIZE,\n weight: 600,\n family: \"Arial\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#000000\",\n },\n lineWidth: OUTLINE_ONLY_GEOMETRY.lineWidth,\n rectProps: OUTLINE_ONLY_GEOMETRY.rectProps,\n stroke: \"#000000\",\n fontWeight: 600,\n shadowOffset: [0, 0],\n shadowColor: \"#000000\",\n shadowBlur: 0,\n },\n [CAPTION_STYLE.SOFT_BOX]: {\n font: {\n size: SOFT_BOX_FONT_SIZE,\n weight: 600,\n family: \"Montserrat\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#333333\",\n },\n lineWidth: SOFT_BOX_GEOMETRY.lineWidth,\n rectProps: SOFT_BOX_GEOMETRY.rectProps,\n stroke: \"#000000\",\n fontWeight: 600,\n shadowOffset: [-1, 1],\n shadowColor: \"rgba(0,0,0,0.3)\",\n shadowBlur: 3,\n },\n };","import { useState, useEffect, useRef } from \"react\";\nimport {\n CAPTION_STYLE,\n CaptionElement,\n Track,\n useTimelineContext,\n} from \"@twick/timeline\";\nimport { CAPTION_PROPS } from \"../helpers/constant\";\n\ninterface CaptionEntry {\n s: number;\n e: number;\n t: string;\n}\n\nexport const useCaptionsPanel = () => {\n const [captions, setCaptions] = useState<CaptionEntry[]>([]);\n const captionsTrack = useRef<Track | null>(null);\n const { editor } = useTimelineContext();\n\n const resolveCaptionTracks = (): Track[] => {\n return (editor.getTimelineData()?.tracks || []).filter(\n (track) => track.getType() === \"caption\"\n );\n };\n\n const fetchCaptions = async () => {\n const captionTracks = resolveCaptionTracks();\n const editorCaptionsTrack = captionTracks[0];\n\n if (!editorCaptionsTrack) {\n captionsTrack.current = null;\n setCaptions([]);\n return;\n }\n\n captionsTrack.current = editorCaptionsTrack;\n setCaptions(\n editorCaptionsTrack.getElements().map((element) => ({\n s: element.getStart(),\n e: element.getEnd(),\n t: (element as CaptionElement).getText(),\n }))\n );\n };\n\n useEffect(() => {\n fetchCaptions();\n }, []);\n\n const checkCaptionsTrack = () => {\n if (!captionsTrack.current) {\n captionsTrack.current = editor.addTrack(\"Caption\", \"caption\");\n const props: Record<string, any> = {\n capStyle: CAPTION_STYLE.WORD_BG_HIGHLIGHT,\n ...CAPTION_PROPS[CAPTION_STYLE.WORD_BG_HIGHLIGHT],\n x: 0,\n y: 200,\n applyToAll: true,\n };\n captionsTrack.current?.setProps(props);\n }\n };\n\n const addCaption = () => {\n const newCaption: CaptionEntry = { s: 0, e: 0, t: \"New Caption\" };\n if (captions.length > 0) {\n newCaption.s = captions[captions.length - 1].e;\n }\n newCaption.e = newCaption.s + 1;\n setCaptions([...captions, newCaption]);\n checkCaptionsTrack();\n const captionElement = new CaptionElement(\n newCaption.t,\n newCaption.s,\n newCaption.e\n );\n editor.addElementToTrack(captionsTrack.current as Track, captionElement);\n };\n\n const splitCaption = async (index: number) => {\n if (captionsTrack.current) {\n const element = captionsTrack.current.getElements()[\n index\n ] as CaptionElement;\n const splitResult = await editor.splitElement(\n element,\n element.getStart() + element.getDuration() / 2\n );\n if (splitResult.success) {\n fetchCaptions();\n }\n }\n };\n\n const deleteCaption = (index: number) => {\n setCaptions(captions.filter((_, i) => i !== index));\n if (captionsTrack.current) {\n editor.removeElement(captionsTrack.current.getElements()[index]);\n }\n };\n\n const updateCaption = (index: number, caption: CaptionEntry) => {\n setCaptions(captions.map((sub, i) => (i === index ? caption : sub)));\n if (captionsTrack.current) {\n const element = captionsTrack.current.getElements()[\n index\n ] as CaptionElement;\n element.setText(caption.t);\n editor.updateElement(element);\n }\n };\n\n return {\n captions,\n addCaption,\n splitCaption,\n deleteCaption,\n updateCaption,\n };\n};\n","import { CaptionsPanel } from \"../panel/captions-panel\";\nimport { useCaptionsPanel } from \"../../hooks/use-captions-panel\";\n\nexport function CaptionsPanelContainer() {\n const captionsPanelProps = useCaptionsPanel();\n return <CaptionsPanel {...captionsPanelProps} />;\n}","import React, { useState, useCallback, useEffect } from \"react\";\nimport { Size, TrackElement } from \"@twick/timeline\";\nimport { ImageElement, VideoElement } from \"@twick/timeline\";\nimport { useLivePlayerContext } from \"@twick/live-player\";\nimport type { StudioConfig } from \"../../types\";\nimport type { ModelInfo } from \"@twick/ai-models\";\n\nconst DEFAULT_IMAGE_DURATION = 5;\n\ninterface GenerateMediaPanelContainerProps {\n videoResolution: Size;\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n studioConfig?: StudioConfig;\n}\n\nexport function GenerateMediaPanelContainer({\n videoResolution,\n addElement,\n studioConfig,\n}: GenerateMediaPanelContainerProps): React.ReactElement {\n const { getCurrentTime } = useLivePlayerContext();\n const [tab, setTab] = useState<\"image\" | \"video\">(\"image\");\n const [prompt, setPrompt] = useState(\"\");\n const [selectedEndpointId, setSelectedEndpointId] = useState(\"\");\n const [isGenerating, setIsGenerating] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [status, setStatus] = useState<string | null>(null);\n\n const imageService = studioConfig?.imageGenerationService;\n const videoService = studioConfig?.videoGenerationService;\n const hasAnyService = !!imageService || !!videoService;\n\n const imageModels = imageService?.getAvailableModels?.() ?? [];\n const videoModels = videoService?.getAvailableModels?.() ?? [];\n const endpoints: ModelInfo[] = tab === \"image\" ? imageModels : videoModels;\n const defaultEndpointId = endpoints[0]?.endpointId ?? \"\";\n const selectedEndpoint =\n endpoints.find((endpoint: ModelInfo) => endpoint.endpointId === selectedEndpointId) ??\n endpoints[0];\n const selectedProvider = selectedEndpoint?.provider;\n\n useEffect(() => {\n if (!selectedEndpointId && defaultEndpointId) {\n setSelectedEndpointId(defaultEndpointId);\n }\n }, [tab, defaultEndpointId, selectedEndpointId]);\n\n const pollStatus = useCallback(\n async (requestId: string) => {\n const service = tab === \"image\" ? imageService : videoService;\n if (!service) return;\n\n const interval = setInterval(async () => {\n try {\n const result = await service.getRequestStatus(requestId);\n if (result.status === \"completed\" && result.url) {\n clearInterval(interval);\n setIsGenerating(false);\n setStatus(null);\n setError(null);\n const currentTime = getCurrentTime();\n const duration = result.duration ?? DEFAULT_IMAGE_DURATION;\n\n if (tab === \"image\") {\n const element = new ImageElement(result.url, videoResolution);\n element.setStart(currentTime);\n element.setEnd(currentTime + duration);\n addElement(element);\n } else {\n const element = new VideoElement(result.url, videoResolution);\n element.setStart(currentTime);\n element.setEnd(currentTime + duration);\n addElement(element);\n }\n } else if (result.status === \"failed\") {\n clearInterval(interval);\n setIsGenerating(false);\n setStatus(null);\n setError(result.error ?? \"Generation failed\");\n }\n } catch {\n // Keep polling\n }\n }, 3000);\n\n return () => clearInterval(interval);\n },\n [tab, imageService, videoService, getCurrentTime, videoResolution, addElement]\n );\n\n const handleGenerate = useCallback(async () => {\n if (!prompt.trim()) {\n setError(\"Enter a prompt\");\n return;\n }\n\n if (tab === \"image\" && !imageService) {\n setError(\"Image generation not configured\");\n return;\n }\n if (tab === \"video\" && !videoService) {\n setError(\"Video generation not configured\");\n return;\n }\n\n setIsGenerating(true);\n setError(null);\n setStatus(\"Starting...\");\n\n try {\n const endpointId = selectedEndpointId || defaultEndpointId;\n const provider = selectedProvider;\n\n if (!endpointId || !provider) {\n setError(\"No model is configured for this tab\");\n setIsGenerating(false);\n setStatus(null);\n return;\n }\n\n if (tab === \"image\" && imageService) {\n const requestId = await imageService.generateImage({\n provider,\n endpointId,\n prompt: prompt.trim(),\n });\n if (requestId) {\n setStatus(\"Generating image...\");\n pollStatus(requestId);\n }\n } else if (tab === \"video\" && videoService) {\n const requestId = await videoService.generateVideo({\n provider,\n endpointId,\n prompt: prompt.trim(),\n });\n if (requestId) {\n setStatus(\"Generating video (this may take several minutes)...\");\n pollStatus(requestId);\n }\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : \"Generation failed\";\n setError(msg);\n setIsGenerating(false);\n setStatus(null);\n }\n }, [\n tab,\n prompt,\n selectedEndpointId,\n defaultEndpointId,\n imageService,\n videoService,\n pollStatus,\n selectedProvider,\n ]);\n\n if (!hasAnyService) {\n return (\n <div className=\"panel-container\">\n <p className=\"empty-state-text\">\n Image and video generation require configuration. Add imageGenerationService\n and videoGenerationService to StudioConfig.\n </p>\n </div>\n );\n }\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-section\">\n <div className=\"flex gap-2 mb-2\">\n <button\n type=\"button\"\n className={`btn-ghost ${tab === \"image\" ? \"active\" : \"\"}`}\n onClick={() => setTab(\"image\")}\n disabled={!imageService}\n >\n Image\n </button>\n <button\n type=\"button\"\n className={`btn-ghost ${tab === \"video\" ? \"active\" : \"\"}`}\n onClick={() => setTab(\"video\")}\n disabled={!videoService}\n >\n Video\n </button>\n </div>\n\n <div className=\"mb-2\">\n <label className=\"block text-sm mb-1\">Model</label>\n <select\n className=\"w-full p-2 border rounded\"\n value={selectedEndpointId}\n onChange={(e) => setSelectedEndpointId(e.target.value)}\n disabled={isGenerating}\n >\n {endpoints.map((ep: ModelInfo) => (\n <option key={ep.endpointId} value={ep.endpointId}>\n {ep.label}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"mb-2\">\n <label className=\"block text-sm mb-1\">Prompt</label>\n <textarea\n className=\"w-full p-2 border rounded min-h-[80px]\"\n value={prompt}\n onChange={(e) => setPrompt(e.target.value)}\n placeholder=\"Describe the image or video you want...\"\n disabled={isGenerating}\n />\n </div>\n\n {error && (\n <div className=\"mb-2 text-red-600 text-sm\">{error}</div>\n )}\n\n {status && (\n <div className=\"mb-2 text-sm text-gray-600\">{status}</div>\n )}\n\n <button\n type=\"button\"\n className=\"btn-primary w-full\"\n onClick={handleGenerate}\n disabled={isGenerating || !prompt.trim()}\n >\n {isGenerating ? \"Generating...\" : `Generate ${tab}`}\n </button>\n </div>\n </div>\n );\n}\n","import type { ProjectTemplate } from \"../types\";\nimport { TRACK_TYPES } from \"@twick/timeline\";\n\nexport const DEFAULT_PROJECT_TEMPLATES: ProjectTemplate[] = [\n {\n id: \"blank-project\",\n name: \"Blank Project\",\n description: \"Start from a clean timeline.\",\n category: \"blank\",\n project: {\n tracks: [],\n version: 1,\n metadata: {\n profile: \"default\",\n templateId: \"blank-project\",\n },\n },\n },\n {\n id: \"edu-lesson\",\n name: \"Lesson Template\",\n description: \"Intro, content, and summary sections for educational videos.\",\n category: \"edu\",\n project: {\n version: 1,\n backgroundColor: \"#0f172a\",\n metadata: {\n profile: \"edu\",\n templateId: \"edu-lesson\",\n chapters: [\n { id: \"chapter-intro\", title: \"Introduction\", time: 0 },\n { id: \"chapter-content\", title: \"Main Lesson\", time: 20 },\n { id: \"chapter-summary\", title: \"Summary\", time: 45 },\n ],\n },\n tracks: [\n {\n id: \"t-edu-text\",\n name: \"Lesson Text\",\n type: TRACK_TYPES.ELEMENT,\n elements: [\n {\n id: \"e-edu-title\",\n trackId: \"t-edu-text\",\n type: \"text\",\n name: \"Title\",\n s: 0,\n e: 6,\n props: {\n text: \"Lesson Title\",\n fontSize: 58,\n fill: \"#ffffff\",\n },\n },\n ],\n },\n ],\n },\n },\n {\n id: \"demo-screen\",\n name: \"Screen Demo\",\n description: \"Template optimized for product demonstrations.\",\n category: \"demo\",\n project: {\n version: 1,\n metadata: {\n profile: \"demo\",\n templateId: \"demo-screen\",\n },\n tracks: [\n {\n id: \"t-demo-video\",\n name: \"Screen Recording\",\n type: TRACK_TYPES.VIDEO,\n elements: [],\n },\n {\n id: \"t-demo-callout\",\n name: \"Callouts\",\n type: TRACK_TYPES.ELEMENT,\n elements: [],\n },\n ],\n },\n },\n];\n","import React from \"react\";\nimport { useTimelineContext, type ProjectJSON } from \"@twick/timeline\";\nimport { DEFAULT_PROJECT_TEMPLATES } from \"../../templates/default-templates\";\nimport type { ProjectTemplate, StudioConfig } from \"../../types\";\n\ninterface TemplateGalleryPanelProps {\n studioConfig?: StudioConfig;\n}\n\nexport const TemplateGalleryPanel = ({\n studioConfig,\n}: TemplateGalleryPanelProps): React.ReactElement => {\n const { editor } = useTimelineContext();\n const templates: ProjectTemplate[] =\n studioConfig?.templates?.length\n ? studioConfig.templates\n : DEFAULT_PROJECT_TEMPLATES;\n\n const loadTemplate = (project: ProjectJSON): void => {\n editor.loadProject(project);\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-header\">\n <h3>Templates</h3>\n </div>\n <div className=\"panel-content\" style={{ display: \"grid\", gap: \"12px\" }}>\n {templates.map((template) => (\n <button\n key={template.id}\n className=\"toolbar-btn\"\n onClick={() => loadTemplate(template.project)}\n style={{\n width: \"100%\",\n justifyContent: \"flex-start\",\n textAlign: \"left\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n padding: \"12px\",\n height: \"auto\",\n }}\n >\n <span style={{ fontWeight: 600 }}>{template.name}</span>\n <span style={{ opacity: 0.8, fontSize: \"12px\" }}>\n {template.description}\n </span>\n <span style={{ opacity: 0.6, fontSize: \"11px\", marginTop: \"2px\" }}>\n {template.category}\n </span>\n </button>\n ))}\n </div>\n </div>\n );\n};\n","import { useRef, useState } from \"react\";\n\ntype RecorderState = \"idle\" | \"recording\" | \"stopped\" | \"error\";\n\ninterface UseScreenRecorderReturn {\n state: RecorderState;\n mediaUrl: string | null;\n error: string | null;\n startRecording: (withMic: boolean) => Promise<void>;\n stopRecording: () => void;\n clearRecording: () => void;\n}\n\nexport const useScreenRecorder = (): UseScreenRecorderReturn => {\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const streamRef = useRef<MediaStream | null>(null);\n const chunksRef = useRef<BlobPart[]>([]);\n\n const [state, setState] = useState<RecorderState>(\"idle\");\n const [mediaUrl, setMediaUrl] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const cleanupStream = () => {\n streamRef.current?.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n };\n\n const startRecording = async (withMic: boolean) => {\n try {\n setError(null);\n if (mediaUrl) {\n URL.revokeObjectURL(mediaUrl);\n setMediaUrl(null);\n }\n\n const displayStream = await navigator.mediaDevices.getDisplayMedia({\n video: true,\n audio: true,\n });\n\n let mixedStream = displayStream;\n if (withMic) {\n const micStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n mixedStream = new MediaStream([\n ...displayStream.getVideoTracks(),\n ...displayStream.getAudioTracks(),\n ...micStream.getAudioTracks(),\n ]);\n }\n\n streamRef.current = mixedStream;\n chunksRef.current = [];\n const recorder = new MediaRecorder(mixedStream, {\n mimeType: \"video/webm\",\n });\n mediaRecorderRef.current = recorder;\n\n recorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n chunksRef.current.push(event.data);\n }\n };\n\n recorder.onerror = () => {\n setState(\"error\");\n setError(\"Recording failed\");\n };\n\n recorder.onstop = () => {\n const blob = new Blob(chunksRef.current, { type: \"video/webm\" });\n const url = URL.createObjectURL(blob);\n setMediaUrl(url);\n setState(\"stopped\");\n cleanupStream();\n };\n\n recorder.start();\n setState(\"recording\");\n } catch (err) {\n setState(\"error\");\n setError(err instanceof Error ? err.message : \"Unable to start recording\");\n cleanupStream();\n }\n };\n\n const stopRecording = () => {\n if (mediaRecorderRef.current && mediaRecorderRef.current.state !== \"inactive\") {\n mediaRecorderRef.current.stop();\n }\n };\n\n const clearRecording = () => {\n if (mediaUrl) {\n URL.revokeObjectURL(mediaUrl);\n }\n cleanupStream();\n setMediaUrl(null);\n setError(null);\n setState(\"idle\");\n };\n\n return {\n state,\n mediaUrl,\n error,\n startRecording,\n stopRecording,\n clearRecording,\n };\n};\n","import React, { useState } from \"react\";\nimport { VideoElement } from \"@twick/timeline\";\nimport type { PanelProps } from \"../../types\";\nimport { useScreenRecorder } from \"../../hooks/use-screen-recorder\";\n\nexport const RecordPanel = ({\n addElement,\n videoResolution,\n}: PanelProps): React.ReactElement => {\n const [withMic, setWithMic] = useState(true);\n const { state, mediaUrl, error, startRecording, stopRecording, clearRecording } =\n useScreenRecorder();\n\n const addToTimeline = async () => {\n if (!mediaUrl || !addElement) return;\n const element = new VideoElement(mediaUrl, videoResolution)\n .setEnd(5)\n .setName(\"Screen Recording\")\n .setMetadata({\n source: \"screen-recording\",\n hasMic: withMic,\n });\n await element.updateVideoMeta();\n const duration = element.getMediaDuration?.() ?? 5;\n element.setEnd(Math.max(1, duration));\n addElement(element);\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-header\">\n <h3>Record Screen</h3>\n </div>\n <div className=\"panel-content\" style={{ display: \"grid\", gap: \"12px\" }}>\n <label style={{ display: \"flex\", gap: \"8px\", alignItems: \"center\" }}>\n <input\n type=\"checkbox\"\n checked={withMic}\n onChange={(e) => setWithMic(e.target.checked)}\n />\n Include microphone\n </label>\n\n {state !== \"recording\" ? (\n <button className=\"btn-primary\" onClick={() => startRecording(withMic)}>\n Start Recording\n </button>\n ) : (\n <button className=\"btn-ghost\" onClick={stopRecording}>\n Stop Recording\n </button>\n )}\n\n {error ? <span className=\"text-sm\">{error}</span> : null}\n\n {mediaUrl ? (\n <>\n <video src={mediaUrl} controls style={{ width: \"100%\", borderRadius: \"8px\" }} />\n <button className=\"btn-primary\" onClick={addToTimeline}>\n Add Recording To Timeline\n </button>\n <button className=\"btn-ghost\" onClick={clearRecording}>\n Clear Recording\n </button>\n </>\n ) : null}\n </div>\n </div>\n );\n};\n","import React from \"react\";\nimport {\n ArrowElement,\n RectElement,\n CircleElement,\n LineElement,\n} from \"@twick/timeline\";\nimport type { PanelProps } from \"../../types\";\n\nconst SHAPE_COLORS = {\n line: \"#f97316\",\n arrow: \"#f59e0b\",\n rect: \"#facc15\",\n circle: \"#facc15\",\n};\n\nexport const AnnotationsPanel = ({\n addElement,\n videoResolution,\n}: PanelProps): React.ReactElement => {\n const addLine = async () => {\n if (!addElement) return;\n const element = new LineElement(SHAPE_COLORS.line, {\n width: Math.round(videoResolution.width * 0.35),\n height: 4,\n })\n .setEnd(5)\n .setName(\"Line\");\n await addElement(element);\n };\n\n const addArrow = async () => {\n if (!addElement) return;\n const element = new ArrowElement(SHAPE_COLORS.arrow, { width: 220, height: 20 })\n .setEnd(5)\n .setName(\"Arrow Callout\");\n await addElement(element);\n };\n\n const addBox = async () => {\n if (!addElement) return;\n const element = new RectElement(SHAPE_COLORS.rect, {\n width: Math.round(videoResolution.width * 0.35),\n height: Math.round(videoResolution.height * 0.18),\n })\n .setEnd(5)\n .setName(\"Box\");\n await addElement(element);\n };\n\n const addCircle = async () => {\n if (!addElement) return;\n const radius = Math.round(Math.min(videoResolution.width, videoResolution.height) * 0.12);\n const element = new CircleElement(SHAPE_COLORS.circle, radius)\n .setEnd(5)\n .setName(\"Circle\");\n await addElement(element);\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-header\">\n <h3>Shapes</h3>\n </div>\n <div\n className=\"panel-content\"\n style={{\n display: \"grid\",\n gap: \"12px\",\n gridTemplateColumns: \"repeat(auto-fit, minmax(140px, 1fr))\",\n }}\n >\n {/* Line */}\n <button\n type=\"button\"\n className=\"btn-ghost\"\n onClick={addLine}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n padding: \"10px 12px\",\n textAlign: \"left\",\n minHeight: 90,\n }}\n >\n <div\n style={{\n height: 6,\n borderRadius: 999,\n background: \"rgba(249,115,22,1)\",\n marginBottom: 8,\n }}\n />\n <div style={{ fontWeight: 600, marginBottom: 2 }}>Line</div>\n <div style={{ fontSize: 12, opacity: 0.8 }}>\n Draw a straight segment to connect or underline.\n </div>\n </button>\n\n {/* Arrow */}\n <button\n type=\"button\"\n className=\"btn-ghost\"\n onClick={addArrow}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n padding: \"10px 12px\",\n textAlign: \"left\",\n minHeight: 90,\n }}\n >\n <div\n style={{\n height: 10,\n borderRadius: 999,\n background: \"rgba(249,115,22,1)\",\n position: \"relative\",\n marginBottom: 8,\n }}\n >\n <div\n style={{\n position: \"absolute\",\n right: -4,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n width: 0,\n height: 0,\n borderTop: \"8px solid transparent\",\n borderBottom: \"8px solid transparent\",\n borderLeft: \"12px solid rgba(249,115,22,1)\",\n }}\n />\n </div>\n <div style={{ fontWeight: 600, marginBottom: 2 }}>Arrow callout</div>\n <div style={{ fontSize: 12, opacity: 0.8 }}>\n Emphasize a button or region with a directional arrow.\n </div>\n </button>\n\n {/* Box (Rect) */}\n <button\n type=\"button\"\n className=\"btn-ghost\"\n onClick={addBox}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n padding: \"10px 12px\",\n textAlign: \"left\",\n minHeight: 90,\n }}\n >\n <div\n style={{\n height: 40,\n borderRadius: 10,\n backgroundColor: \"rgba(250,204,21,0.35)\",\n border: \"1px solid rgba(250,204,21,0.8)\",\n marginBottom: 8,\n }}\n />\n <div style={{ fontWeight: 600, marginBottom: 2 }}>Box</div>\n <div style={{ fontSize: 12, opacity: 0.8 }}>\n Draw attention to important text or UI with a soft highlight.\n </div>\n </button>\n\n {/* Circle */}\n <button\n type=\"button\"\n className=\"btn-ghost\"\n onClick={addCircle}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n padding: \"10px 12px\",\n textAlign: \"left\",\n minHeight: 90,\n }}\n >\n <div\n style={{\n height: 40,\n width: 40,\n borderRadius: 999,\n border: \"2px solid rgba(250,204,21,0.9)\",\n backgroundColor: \"rgba(250,204,21,0.2)\",\n marginBottom: 8,\n alignSelf: \"flex-start\",\n }}\n />\n <div style={{ fontWeight: 600, marginBottom: 2 }}>Circle</div>\n <div style={{ fontSize: 12, opacity: 0.8 }}>\n Add a circular callout or highlight area.\n </div>\n </button>\n </div>\n </div>\n );\n};\n","import React, { useMemo, useState } from \"react\";\nimport { useTimelineContext, type ChapterMarker } from \"@twick/timeline\";\nimport { useLivePlayerContext } from \"@twick/live-player\";\nimport type { PanelProps } from \"../../types\";\n\nconst sortChapters = (chapters: ChapterMarker[]): ChapterMarker[] =>\n [...chapters].sort((a, b) => a.time - b.time);\n\nexport const ChaptersPanel = (_props: PanelProps): React.ReactElement => {\n const { editor, present } = useTimelineContext();\n const { getCurrentTime } = useLivePlayerContext();\n const [title, setTitle] = useState(\"\");\n\n const chapters = useMemo(\n () => sortChapters(present?.metadata?.chapters ?? []),\n [present?.metadata?.chapters]\n );\n\n const persistChapters = (nextChapters: ChapterMarker[]) => {\n const metadata = editor.getMetadata() ?? {};\n editor.setMetadata({\n ...metadata,\n chapters: sortChapters(nextChapters),\n });\n };\n\n const addChapter = () => {\n if (!title.trim()) return;\n const time = getCurrentTime();\n const next: ChapterMarker = {\n id: `chapter-${Date.now()}`,\n title: title.trim(),\n time,\n };\n persistChapters([...(chapters || []), next]);\n setTitle(\"\");\n };\n\n const removeChapter = (id: string) => {\n persistChapters(chapters.filter((chapter) => chapter.id !== id));\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-header\">\n <h3>Chapters</h3>\n </div>\n <div className=\"panel-content\" style={{ display: \"grid\", gap: \"10px\" }}>\n <input\n className=\"search-input\"\n placeholder=\"Chapter title at current playhead\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n />\n <button className=\"btn-primary\" onClick={addChapter}>\n Add Chapter At Playhead\n </button>\n <div style={{ display: \"grid\", gap: \"8px\" }}>\n {chapters.map((chapter) => (\n <div\n key={chapter.id}\n className=\"btn-ghost\"\n style={{\n width: \"100%\",\n height: \"auto\",\n justifyContent: \"space-between\",\n padding: \"8px 10px\",\n }}\n >\n <span>\n {Math.floor(chapter.time)}s - {chapter.title}\n </span>\n <button\n className=\"btn-ghost\"\n style={{ padding: \"2px 6px\" }}\n onClick={() => removeChapter(chapter.id)}\n >\n Remove\n </button>\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n};\n","import React, { useState } from \"react\";\nimport { TextElement, type ChapterMarker, useTimelineContext } from \"@twick/timeline\";\nimport type { PanelProps } from \"../../types\";\n\nconst parseSections = (script: string): string[] =>\n script\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => !!line);\n\nexport const ScriptPanel = ({ videoResolution }: PanelProps): React.ReactElement => {\n const [script, setScript] = useState(\"\");\n const { editor } = useTimelineContext();\n\n const buildTimelineFromScript = async () => {\n const sections = parseSections(script);\n if (!sections.length) return;\n\n const chapters: ChapterMarker[] = [];\n const track = editor.addTrack(\"Script Outline\", \"element\");\n\n for (let index = 0; index < sections.length; index++) {\n const section = sections[index];\n const start = index * 6;\n const end = start + 5;\n chapters.push({\n id: `script-chapter-${Date.now()}-${index}`,\n title: section,\n time: start,\n });\n const textElement = new TextElement(section)\n .setStart(start)\n .setEnd(end)\n .setName(`Script Section ${index + 1}`)\n .setPosition({\n x: Math.round(videoResolution.width / 2),\n y: Math.round(videoResolution.height * 0.2),\n });\n await editor.addElementToTrack(track, textElement);\n }\n\n const metadata = editor.getMetadata() ?? {};\n editor.setMetadata({\n ...metadata,\n chapters: [...(metadata.chapters ?? []), ...chapters],\n });\n editor.refresh();\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-header\">\n <h3>Script</h3>\n </div>\n <div className=\"panel-content\" style={{ display: \"grid\", gap: \"10px\" }}>\n <textarea\n className=\"input-dark\"\n rows={10}\n placeholder=\"Paste script outline (one section per line)\"\n value={script}\n onChange={(e) => setScript(e.target.value)}\n />\n <button className=\"btn-primary\" onClick={buildTimelineFromScript}>\n Generate Timeline From Outline\n </button>\n </div>\n </div>\n );\n};\n","import React from \"react\";\nimport { Size, TrackElement } from \"@twick/timeline\";\nimport type { StudioConfig, UploadConfig } from \"../../types\";\nimport { AudioPanelContainer } from \"./audio-panel-container\";\nimport { ImagePanelContainer } from \"./image-panel-container\";\nimport { VideoPanelContainer } from \"./video-panel-container\";\nimport { TextPanelContainer } from \"./text-panel-container\";\nimport { TextStylePanelContainer } from \"./text-style-panel-container\";\nimport { EffectStylePanelContainer } from \"./effect-style-panel-container\";\nimport { Wand2 } from \"lucide-react\";\nimport { CaptionsPanelContainer } from \"./captions-panel-container\";\nimport { GenerateMediaPanelContainer } from \"./generate-media-panel-container\";\nimport { TemplateGalleryPanel } from \"../panel/template-gallery-panel\";\nimport { RecordPanel } from \"../panel/record-panel\";\nimport { AnnotationsPanel } from \"../panel/annotations-panel\";\nimport { ChaptersPanel } from \"../panel/chapters-panel\";\nimport { ScriptPanel } from \"../panel/script-panel\";\n\n/**\n * Props interface for the ElementPanelContainer component.\n * Defines the configuration and callback functions for element management.\n */\ninterface ElementPanelContainerProps {\n selectedTool: string;\n selectedElement: TrackElement | null;\n videoResolution: Size;\n setSelectedTool: (tool: string) => void;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n uploadConfig?: UploadConfig;\n studioConfig?: StudioConfig;\n}\n\n/**\n * ElementPanelContainer component that renders the appropriate element panel\n * based on the currently selected tool. Provides a unified interface for\n * managing different types of timeline elements including media, text, shapes,\n * and captions. Shows an empty state when no tool is selected.\n *\n * @param props - Component props for element panel configuration\n * @returns JSX element containing the appropriate element panel or empty state\n * \n * @example\n * ```tsx\n * <ElementPanelContainer\n * selectedTool=\"text\"\n * selectedElement={currentElement}\n * videoResolution={{ width: 1920, height: 1080 }}\n * setSelectedTool={setTool}\n * addElement={addToTimeline}\n * updateElement={updateInTimeline}\n * />\n * ```\n */\nconst ElementPanelContainer = ({\n selectedTool,\n videoResolution,\n selectedElement,\n addElement,\n updateElement,\n setSelectedTool,\n uploadConfig,\n studioConfig,\n}: ElementPanelContainerProps): React.ReactElement => {\n const addNewElement = async (element: TrackElement) => {\n await addElement(element);\n };\n\n // Render appropriate library based on selected tool\n const renderLibrary = () => {\n const CustomPanel = studioConfig?.customPanels?.[selectedTool];\n if (CustomPanel) {\n return (\n <CustomPanel\n selectedElement={selectedElement}\n videoResolution={videoResolution}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n studioConfig={studioConfig}\n />\n );\n }\n\n switch (selectedTool) {\n case \"image\":\n return (\n <ImagePanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n />\n );\n case \"audio\":\n return (\n <AudioPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n />\n );\n case \"video\":\n return (\n <VideoPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n />\n );\n case \"text\":\n return (\n <TextPanelContainer\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"text-style\":\n return (\n <TextStylePanelContainer\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"effect\":\n return (\n <EffectStylePanelContainer\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"caption\":\n return <CaptionsPanelContainer />;\n case \"generate-media\":\n return (\n <GenerateMediaPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n studioConfig={studioConfig}\n />\n );\n case \"templates\":\n return <TemplateGalleryPanel studioConfig={studioConfig} />;\n case \"record\":\n return (\n <RecordPanel\n selectedElement={selectedElement}\n videoResolution={videoResolution}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n studioConfig={studioConfig}\n />\n );\n case \"shape\":\n return (\n <AnnotationsPanel\n selectedElement={selectedElement}\n videoResolution={videoResolution}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n studioConfig={studioConfig}\n />\n );\n case \"chapters\":\n return (\n <ChaptersPanel\n selectedElement={selectedElement}\n videoResolution={videoResolution}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n studioConfig={studioConfig}\n />\n );\n case \"script\":\n return (\n <ScriptPanel\n selectedElement={selectedElement}\n videoResolution={videoResolution}\n addElement={addNewElement}\n updateElement={updateElement}\n uploadConfig={uploadConfig}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n studioConfig={studioConfig}\n />\n );\n default:\n return (\n <div className=\"panel-container\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Wand2 className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">Select an element from toolbar</p>\n </div>\n </div>\n </div>\n );\n }\n };\n\n return renderLibrary();\n};\n\nexport default ElementPanelContainer;\n","import type { ReactNode } from \"react\";\n\ninterface PropertyRowProps {\n label: string;\n children: ReactNode;\n /** Optional secondary label/value on the right (e.g. units, current value) */\n secondary?: ReactNode;\n}\n\nexport function PropertyRow({ label, children, secondary }: PropertyRowProps) {\n return (\n <div className=\"property-row\">\n <div className=\"property-row-label\">\n <span className=\"property-label\">{label}</span>\n </div>\n <div className=\"property-row-control\">\n {children}\n </div>\n {secondary && (\n <div className=\"property-row-secondary\">\n {secondary}\n </div>\n )}\n </div>\n );\n}\n\n","import { ChevronDown, ChevronRight } from \"lucide-react\";\n\ninterface AccordionItemProps {\n title: string;\n icon: React.ReactNode;\n children: React.ReactNode;\n isOpen: boolean;\n onToggle: () => void;\n}\n\nexport function AccordionItem({ title, icon, children, isOpen, onToggle }: AccordionItemProps) {\n return (\n <div className=\"accordion-item\">\n <div\n onClick={onToggle}\n className=\"accordion-header\"\n >\n <div className=\"flex-container\">\n <div className=\"accent-purple\">\n {icon}\n </div>\n <span className=\"property-title\">{title}</span>\n </div>\n {isOpen ? (\n <ChevronDown className=\"icon-sm accent-purple\" />\n ) : (\n <ChevronRight className=\"icon-sm accent-purple\" />\n )}\n </div>\n <div\n className={`accordion-content ${isOpen ? 'expanded' : ''}`}\n >\n <div className=\"accordion-panel\">\n {children}\n </div>\n </div>\n </div>\n );\n}\n","import { RectElement, CircleElement, TrackElement } from \"@twick/timeline\";\n// Dimensions in inspector: Rect and Circle only. Image/Video resize via canvas (dimensions deferred).\nimport type { PropertiesPanelProps } from \"../../types\";\nimport { PropertyRow } from \"./property-row\";\nimport { Ruler } from \"lucide-react\";\nimport { AccordionItem } from \"../shared/accordion-item\";\nimport { useState } from \"react\";\n\nexport function ElementProps({ selectedElement, updateElement }: PropertiesPanelProps) {\n const opacity = selectedElement?.getOpacity() || 1;\n const rotation = selectedElement?.getRotation() || 0;\n const position = selectedElement?.getPosition() || { x: 0, y: 0 };\n\n const handleRotationChange = (rotation: number) => {\n if (selectedElement) {\n selectedElement.setRotation(rotation);\n updateElement?.(selectedElement as TrackElement);\n }\n }\n\n const handleOpacityChange = (opacity: number) => {\n if (selectedElement) {\n selectedElement.setOpacity(opacity);\n updateElement?.(selectedElement as TrackElement);\n }\n }\n const handlePositionChange = (props: Record<string, any>) => {\n if (selectedElement) {\n selectedElement.setPosition({ x: props.x ?? 0, y: props.y ?? 0 });\n updateElement?.(selectedElement as TrackElement);\n }\n }\n\n const handleDimensionsChange = (width?: number, height?: number) => {\n if (!selectedElement) return;\n if (selectedElement instanceof RectElement) {\n const size = selectedElement.getSize();\n selectedElement.setSize({ width: width ?? size.width, height: height ?? size.height });\n updateElement?.(selectedElement as TrackElement);\n } else if (selectedElement instanceof CircleElement) {\n const dims = {\n width: selectedElement.getRadius() * 2,\n height: selectedElement.getRadius() * 2,\n };\n const newDiameter =\n width !== undefined && width !== dims.width ? width : (height ?? dims.height);\n selectedElement.setRadius(newDiameter / 2);\n updateElement?.(selectedElement as TrackElement);\n }\n }\n\n const hasShapeDimensions =\n selectedElement instanceof RectElement || selectedElement instanceof CircleElement;\n\n let dimensions: { width: number; height: number } | null = null;\n if (selectedElement instanceof RectElement) {\n dimensions = selectedElement.getSize();\n } else if (selectedElement instanceof CircleElement) {\n const r = selectedElement.getRadius();\n dimensions = { width: r * 2, height: r * 2 };\n }\n\n const [isTransformOpen, setIsTransformOpen] = useState(false);\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Properties</div>\n\n <AccordionItem\n title=\"Transform\"\n icon={<Ruler className=\"icon-sm\" />}\n isOpen={isTransformOpen}\n onToggle={() => setIsTransformOpen((open) => !open)}\n >\n <div className=\"properties-group\">\n <div className=\"property-section\">\n <PropertyRow label=\"Position X\">\n <input\n type=\"number\"\n value={position.x ?? 0}\n onChange={(e) =>\n handlePositionChange({ x: Number(e.target.value) })\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n <PropertyRow label=\"Position Y\">\n <input\n type=\"number\"\n value={position.y ?? 0}\n onChange={(e) =>\n handlePositionChange({ y: Number(e.target.value) })\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n </div>\n\n {/* Dimensions - for rect, circle only; image/video resize via canvas */}\n {hasShapeDimensions && dimensions && (\n <div className=\"property-section\">\n <PropertyRow label=\"Width\">\n <input\n type=\"number\"\n min={1}\n value={Math.round(dimensions.width)}\n onChange={(e) =>\n handleDimensionsChange(\n Number(e.target.value),\n dimensions!.height\n )\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n <PropertyRow label=\"Height\">\n <input\n type=\"number\"\n min={1}\n value={Math.round(dimensions.height)}\n onChange={(e) =>\n handleDimensionsChange(\n dimensions!.width,\n Number(e.target.value)\n )\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n </div>\n )}\n\n {/* Opacity */}\n <div className=\"property-section\">\n <PropertyRow\n label=\"Opacity\"\n secondary={\n <span>\n {Math.round((opacity ?? 1) * 100)}\n %\n </span>\n }\n >\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n value={(opacity ?? 1) * 100}\n onChange={(e) =>\n handleOpacityChange(Number(e.target.value) / 100)\n }\n className=\"slider-purple\"\n />\n </PropertyRow>\n </div>\n\n {/* Rotation */}\n <div className=\"property-section\">\n <PropertyRow\n label=\"Rotation\"\n secondary={\n <span>\n {Math.round(rotation ?? 0)}\n °\n </span>\n }\n >\n <input\n type=\"range\"\n min=\"0\"\n max=\"360\"\n value={rotation ?? 0}\n onChange={(e) => handleRotationChange(Number(e.target.value))}\n className=\"slider-purple\"\n />\n </PropertyRow>\n </div>\n </div>\n </AccordionItem>\n </div>\n );\n}\n","import { TEXT_EFFECTS } from \"@twick/video-editor\";\nimport { ElementTextEffect, TextElement } from \"@twick/timeline\";\nimport type { PropertiesPanelProps } from \"../../types\";\nimport { AccordionItem } from \"../shared/accordion-item\";\nimport { PropertyRow } from \"./property-row\";\nimport { SparklesIcon } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport function TextEffects({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n if (!(selectedElement instanceof TextElement)) return null;\n\n const currentEffect = selectedElement.getTextEffect();\n\n const handleUpdateEffect = (props: {\n name?: string;\n delay?: number;\n duration?: number;\n bufferTime?: number;\n }) => {\n if (!selectedElement || !(selectedElement instanceof TextElement)) return;\n\n let effect = currentEffect;\n\n // If name is provided and empty, remove effect\n if (props.name === \"\") {\n selectedElement.setTextEffect(undefined);\n updateElement?.(selectedElement);\n return;\n }\n\n // Create new effect if none exists or name is changing\n if (!effect || (props.name && props.name !== effect.getName())) {\n effect = new ElementTextEffect(\n props.name || currentEffect?.getName() || TEXT_EFFECTS[0].name\n );\n // Set default values for new effect\n effect.setDelay(0);\n effect.setDuration(1);\n effect.setBufferTime(0.1);\n }\n\n // Update effect properties\n if (props.delay !== undefined) effect.setDelay(props.delay);\n if (props.duration !== undefined) effect.setDuration(props.duration);\n if (props.bufferTime !== undefined) effect.setBufferTime(props.bufferTime);\n\n // Update element with new/modified effect\n selectedElement.setTextEffect(effect);\n updateElement?.(selectedElement);\n };\n\n const [isEffectsOpen, setIsEffectsOpen] = useState(false);\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Text Effects</div>\n <AccordionItem\n title=\"Effects\"\n icon={<SparklesIcon className=\"icon-sm\" />}\n isOpen={isEffectsOpen}\n onToggle={() => setIsEffectsOpen((open) => !open)}\n >\n <div className=\"properties-group\">\n {/* Text Effect Selection */}\n <div className=\"property-section\">\n <PropertyRow label=\"Preset\">\n <select\n value={currentEffect?.getName() || \"\"}\n onChange={(e) => handleUpdateEffect({ name: e.target.value })}\n className=\"select-dark w-full\"\n >\n <option value=\"\">No Effect</option>\n {TEXT_EFFECTS.map((effect) => (\n <option key={effect.name} value={effect.name}>\n {effect.name.charAt(0).toUpperCase() + effect.name.slice(1)}\n </option>\n ))}\n </select>\n </PropertyRow>\n </div>\n\n {/* Text Effect Options */}\n {currentEffect && (\n <>\n {/* Delay */}\n <div className=\"property-section\">\n <PropertyRow label=\"Delay (s)\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"5\"\n step=\"0.1\"\n value={currentEffect.getDelay() ?? 0}\n onChange={(e) =>\n handleUpdateEffect({ delay: Number(e.target.value) })\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n </div>\n\n {/* Duration */}\n <div className=\"property-section\">\n <PropertyRow label=\"Duration (s)\">\n <input\n type=\"number\"\n min=\"0.1\"\n max=\"10\"\n step=\"0.1\"\n value={currentEffect.getDuration() ?? 1}\n onChange={(e) =>\n handleUpdateEffect({ duration: Number(e.target.value) })\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n </div>\n\n {/* Buffer Time */}\n <div className=\"property-section\">\n <PropertyRow label=\"Buffer (s)\">\n <input\n type=\"number\"\n min=\"0.05\"\n max=\"1\"\n step=\"0.05\"\n value={currentEffect.getBufferTime() ?? 0.1}\n onChange={(e) =>\n handleUpdateEffect({\n bufferTime: Number(e.target.value),\n })\n }\n className=\"input-dark\"\n />\n </PropertyRow>\n </div>\n </>\n )}\n </div>\n </AccordionItem>\n </div>\n );\n}\n","import { ANIMATIONS } from \"@twick/video-editor\";\nimport { ElementAnimation, TrackElement } from \"@twick/timeline\";\nimport type { PropertiesPanelProps } from \"../../types\";\n\nexport function Animation({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n if (!(selectedElement instanceof TrackElement)) return null;\n\n const currentAnimation = selectedElement?.getAnimation();\n\n const handleUpdateAnimation = (props: {\n name?: string;\n interval?: number;\n duration?: number;\n intensity?: number;\n animate?: \"enter\" | \"exit\" | \"both\";\n mode?: \"in\" | \"out\";\n direction?: \"up\" | \"down\" | \"left\" | \"right\" | \"center\";\n }) => {\n if (!selectedElement) return;\n\n let animation = currentAnimation;\n\n // If name is provided and empty, remove animation\n if (props.name === \"\") {\n selectedElement.setAnimation(undefined);\n updateElement?.(selectedElement);\n return;\n }\n\n // Find animation definition\n const animationDef = ANIMATIONS.find(\n (a) => a.name === (props.name || currentAnimation?.getName())\n );\n if (!animationDef) return;\n\n // Create new animation if none exists or name is changing\n if (!animation || (props.name && props.name !== animation.getName())) {\n animation = new ElementAnimation(\n props.name || currentAnimation?.getName() || ANIMATIONS[0].name\n );\n // Set default values for new animation\n animation.setInterval(animationDef.interval || 1);\n animation.setDuration(animationDef.duration || 1);\n animation.setIntensity(animationDef.intensity || 1);\n animation.setAnimate(animationDef.animate || \"enter\");\n if (animationDef.mode) animation.setMode(animationDef.mode);\n if (animationDef.direction)\n animation.setDirection(animationDef.direction);\n }\n\n // Update animation properties with validation\n if (props.interval !== undefined) {\n const [min, max] = animationDef.options?.interval || [0.1, 5];\n animation.setInterval(Math.min(Math.max(props.interval, min), max));\n }\n if (props.duration !== undefined) {\n const [min, max] = animationDef.options?.duration || [0.1, 5];\n animation.setDuration(Math.min(Math.max(props.duration, min), max));\n }\n if (props.intensity !== undefined) {\n const [min, max] = animationDef.options?.intensity || [0.1, 2];\n animation.setIntensity(Math.min(Math.max(props.intensity, min), max));\n }\n if (\n props.animate &&\n animationDef.options?.animate?.includes(props.animate)\n ) {\n animation.setAnimate(props.animate);\n }\n if (props.mode && animationDef.options?.mode?.includes(props.mode)) {\n animation.setMode(props.mode);\n }\n if (\n props.direction &&\n animationDef.options?.direction?.includes(props.direction)\n ) {\n animation.setDirection(props.direction);\n }\n\n // Update element with new/modified animation\n selectedElement.setAnimation(animation);\n updateElement?.(selectedElement);\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Animations</div>\n {/* Animation Selection */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Type</label>\n <select\n value={currentAnimation?.getName() || \"\"}\n onChange={(e) => handleUpdateAnimation({ name: e.target.value })}\n className=\"select-dark w-full\"\n >\n <option value=\"\">No Animation</option>\n {ANIMATIONS.map((animation) => (\n <option key={animation.name} value={animation.name}>\n {animation.name.charAt(0).toUpperCase() + animation.name.slice(1)}\n </option>\n ))}\n </select>\n </div>\n\n {/* Animation Options */}\n {currentAnimation && (\n <>\n {/* Get current animation definition */}\n {(() => {\n const animationDef = ANIMATIONS.find(\n (a) => a.name === currentAnimation.getName()\n );\n if (!animationDef || !animationDef.options) return null;\n\n return (\n <>\n {/* Animate */}\n {animationDef.options?.animate && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">When to Animate</label>\n <select\n value={currentAnimation.getAnimate()}\n onChange={(e) =>\n handleUpdateAnimation({\n animate: e.target.value as\n | \"enter\"\n | \"exit\"\n | \"both\",\n })\n }\n className=\"select-dark w-full\"\n >\n {animationDef.options?.animate.map((option) => (\n <option key={option} value={option}>\n {option.charAt(0).toUpperCase() + option.slice(1)}\n </option>\n ))}\n </select>\n </div>\n )}\n\n {/* Direction */}\n {animationDef.options?.direction && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Direction</label>\n <select\n value={currentAnimation.getDirection()}\n onChange={(e) =>\n handleUpdateAnimation({\n direction: e.target.value as\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | \"center\",\n })\n }\n className=\"select-dark w-full\"\n >\n {animationDef.options?.direction.map((option) => (\n <option key={option} value={option}>\n {option.charAt(0).toUpperCase() + option.slice(1)}\n </option>\n ))}\n </select>\n </div>\n )}\n\n {/* Mode */}\n {animationDef.options?.mode && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Mode</label>\n <select\n value={currentAnimation.getMode()}\n onChange={(e) =>\n handleUpdateAnimation({\n mode: e.target.value as \"in\" | \"out\",\n })\n }\n className=\"select-dark w-full\"\n >\n {animationDef.options?.mode.map((option) => (\n <option key={option} value={option}>\n {option.charAt(0).toUpperCase() + option.slice(1)}\n </option>\n ))}\n </select>\n </div>\n )}\n\n {/* Duration */}\n {animationDef.options?.duration && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Duration (seconds)</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min={animationDef.options?.duration[0]}\n max={animationDef.options?.duration[1]}\n step=\"0.1\"\n value={currentAnimation.getDuration()}\n onChange={(e) =>\n handleUpdateAnimation({\n duration: Number(e.target.value),\n })\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{currentAnimation.getDuration()}</span>\n </div>\n </div>\n )}\n\n {/* Interval */}\n {animationDef.options?.interval && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Interval (seconds)</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min={animationDef.options?.interval[0]}\n max={animationDef.options?.interval[1]}\n step=\"0.1\"\n value={currentAnimation.getInterval()}\n onChange={(e) =>\n handleUpdateAnimation({\n interval: Number(e.target.value),\n })\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{currentAnimation.getInterval()}</span>\n </div>\n </div>\n )}\n\n {/* Intensity */}\n {animationDef.options?.intensity && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Intensity</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min={animationDef.options?.intensity[0]}\n max={animationDef.options?.intensity[1]}\n step=\"0.1\"\n value={currentAnimation.getIntensity()}\n onChange={(e) =>\n handleUpdateAnimation({\n intensity: Number(e.target.value),\n })\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{currentAnimation.getIntensity()}</span>\n </div>\n </div>\n )}\n </>\n );\n })()}\n </>\n )}\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport {\n CaptionElement,\n CAPTION_STYLE,\n CAPTION_STYLE_OPTIONS,\n computeCaptionGeometry,\n useTimelineContext,\n} from \"@twick/timeline\";\nimport { AVAILABLE_TEXT_FONTS } from \"@twick/video-editor\";\nimport { PropertiesPanelProps } from \"../../types\";\n\nexport { CAPTION_STYLE, CAPTION_STYLE_OPTIONS };\n\nexport const CAPTION_FONT = {\n size: 40,\n family: \"Bangers\",\n};\n\nexport const CAPTION_COLOR = {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#8C52FF\",\n outlineColor: \"#000000\",\n};\n\ntype CaptionColorKey = keyof typeof CAPTION_COLOR;\n\ntype CaptionStyleColorMeta = {\n usedColors: CaptionColorKey[];\n labels: Partial<Record<CaptionColorKey, string>>;\n};\n\ntype CaptionColorsState = {\n text: string;\n highlight?: string;\n bgColor?: string;\n outlineColor?: string;\n};\n\nconst CAPTION_STYLE_COLOR_META: Record<string, CaptionStyleColorMeta> = {\n // Word background highlight - white text on colored pill\n highlight_bg: {\n // Text color, and background pill color used in animation.\n usedColors: [\"text\", \"bgColor\"],\n labels: {\n text: \"Text Color\",\n bgColor: \"Highlight Background\",\n },\n },\n // Simple word-by-word – text only\n word_by_word: {\n // Visualizer uses text as fill + outlineColor for stroke, and highlight for active word.\n usedColors: [\"text\", \"highlight\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Word-by-word with a phrase bar background\n word_by_word_with_bg: {\n // Text color (fill), highlight for active word, outlineColor (stroke), bgColor used by phrase rect.\n usedColors: [\"text\", \"highlight\", \"bgColor\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n bgColor: \"Bar Background\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Classic outlined text\n outline_only: {\n // Outline-only style: fill + outline color; highlight not used in animation.\n usedColors: [\"text\", \"outlineColor\"],\n labels: {\n text: \"Fill Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Soft rounded box behind text\n soft_box: {\n usedColors: [\"text\", \"bgColor\", \"highlight\", \"outlineColor\", ],\n labels: {\n text: \"Text Color\",\n highlight: \"Highlight Color\",\n bgColor: \"Box Background\",\n outlineColor: \"Outline Color\",\n },\n },\n // Broadcast style lower-third bar\n lower_third: {\n // Title text, bar background, highlight color and outline color.\n usedColors: [\"text\", \"bgColor\", \"outlineColor\"],\n labels: {\n text: \"Title Text Color\",\n bgColor: \"Bar Background\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Typewriter – text only\n typewriter: {\n // Text color and outline color (stroke) used by visualizer; highlight not animated.\n usedColors: [\"text\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Karaoke – base text plus active word highlight\n karaoke: {\n // Base text color, active word highlight color, outline color.\n usedColors: [\"text\", \"highlight\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Karaoke-word – single active word, previous words dimmed\n \"karaoke-word\": {\n // Same color needs as karaoke.\n usedColors: [\"text\", \"highlight\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n // Pop / scale – text only\n pop_scale: {\n // Text color, highlight color for active word, and outline color; no background.\n usedColors: [\"text\", \"highlight\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n },\n },\n};\n\nconst DEFAULT_COLOR_META: CaptionStyleColorMeta = {\n usedColors: [\"text\", \"bgColor\", \"outlineColor\"],\n labels: {\n text: \"Text Color\",\n bgColor: \"Background Color\",\n outlineColor: \"Outline Color\",\n },\n};\n\nconst CAPTION_FONTS = Object.values(AVAILABLE_TEXT_FONTS);\n\ninterface CaptionPropPanelProps {\n /** No-op when using fixed config. Kept for API compatibility. */\n setApplyPropsToAllCaption?: (apply: boolean) => void;\n}\n\nexport function CaptionPropPanel({\n selectedElement,\n updateElement,\n}: CaptionPropPanelProps & PropertiesPanelProps) {\n const { editor, changeLog } = useTimelineContext();\n const captionRef = useRef<HTMLInputElement>(null);\n const [capStyle, setCapStyle] = useState<(typeof CAPTION_STYLE_OPTIONS)[keyof typeof CAPTION_STYLE_OPTIONS]>(\n CAPTION_STYLE_OPTIONS[CAPTION_STYLE.WORD_BG_HIGHLIGHT]\n );\n const [fontSize, setFontSize] = useState(CAPTION_FONT.size);\n const [fontFamily, setFontFamily] = useState(CAPTION_FONT.family);\n const [colors, setColors] = useState<CaptionColorsState>({\n text: CAPTION_COLOR.text,\n highlight: CAPTION_COLOR.highlight,\n bgColor: CAPTION_COLOR.bgColor,\n outlineColor: CAPTION_COLOR.outlineColor,\n });\n const [useHighlight, setUseHighlight] = useState(true);\n const [useOutline, setUseOutline] = useState(true);\n\n const track = selectedElement instanceof CaptionElement\n ? editor.getTrackById(selectedElement.getTrackId())\n : null;\n const trackProps = track?.getProps() ?? {};\n const applyToAll = trackProps?.applyToAll ?? false;\n\n const handleUpdateCaption = (updates: {\n text?: string;\n style?: string;\n fontSize?: number;\n fontFamily?: string;\n colors?: CaptionColorsState;\n useHighlightOverride?: boolean;\n useOutlineOverride?: boolean;\n }) => {\n const captionElement = selectedElement as CaptionElement;\n if (!captionElement) return;\n\n const nextFontSize = updates.fontSize ?? fontSize;\n const geometry = computeCaptionGeometry(nextFontSize, updates.style ?? capStyle?.value ?? \"\");\n\n // Decide which colors to persist based on highlight toggle.\n const highlightEnabled = updates.useHighlightOverride ?? useHighlight;\n const outlineEnabled = updates.useOutlineOverride ?? useOutline;\n const rawNextColors: CaptionColorsState = updates.colors ?? colors;\n\n // Start with raw colors, then drop highlight / outlineColor keys when disabled.\n let effectiveColors: CaptionColorsState = { ...rawNextColors };\n if (!highlightEnabled) {\n const { highlight, ...rest } = effectiveColors;\n effectiveColors = rest;\n }\n if (!outlineEnabled) {\n const { outlineColor, ...rest } = effectiveColors;\n effectiveColors = rest;\n }\n\n if (applyToAll && track) {\n const nextFont = {\n size: nextFontSize,\n family: updates.fontFamily ?? fontFamily,\n };\n const nextColors = effectiveColors;\n const nextCapStyle = updates.style ?? capStyle?.value;\n\n track.setProps({\n ...trackProps,\n capStyle: nextCapStyle,\n font: { ...(trackProps?.font ?? {}), ...nextFont },\n colors: nextColors,\n lineWidth: geometry.lineWidth,\n rectProps: geometry.rectProps,\n });\n editor.refresh();\n } else {\n const elementProps = captionElement.getProps() ?? {};\n captionElement.setProps({\n ...elementProps,\n capStyle: updates.style ?? capStyle?.value,\n font: {\n size: nextFontSize,\n family: updates.fontFamily ?? fontFamily,\n },\n colors: effectiveColors,\n lineWidth: geometry.lineWidth,\n });\n updateElement?.(captionElement);\n }\n };\n\n useEffect(() => {\n const captionElement = selectedElement as CaptionElement;\n if (captionElement) {\n if (captionRef.current) {\n captionRef.current.value = captionElement?.getText();\n }\n const props = applyToAll ? trackProps : (captionElement.getProps() ?? {});\n const _capStyle = props?.capStyle;\n if (_capStyle && _capStyle in CAPTION_STYLE_OPTIONS) {\n setCapStyle(CAPTION_STYLE_OPTIONS[_capStyle as keyof typeof CAPTION_STYLE_OPTIONS]);\n }\n setFontSize(props?.font?.size ?? CAPTION_FONT.size);\n setFontFamily(props?.font?.family ?? CAPTION_FONT.family);\n const c = props?.colors;\n setColors({\n text: c?.text ?? CAPTION_COLOR.text,\n highlight: c?.highlight ?? CAPTION_COLOR.highlight,\n bgColor: c?.bgColor ?? CAPTION_COLOR.bgColor,\n outlineColor: c?.outlineColor ?? CAPTION_COLOR.outlineColor,\n });\n setUseHighlight(c?.highlight != null);\n setUseOutline(c?.outlineColor != null);\n }\n }, [selectedElement, applyToAll, changeLog]);\n\n if (!(selectedElement instanceof CaptionElement)) {\n return null;\n }\n\n const currentStyleKey = capStyle?.value as string | undefined;\n const currentColorMeta =\n (currentStyleKey && CAPTION_STYLE_COLOR_META[currentStyleKey]) ||\n DEFAULT_COLOR_META;\n\n const defaultColorLabels: Record<CaptionColorKey, string> = {\n text: \"Text Color\",\n bgColor: \"Background Color\",\n highlight: \"Highlight Color\",\n outlineColor: \"Outline Color\",\n };\n\n const renderColorControl = (key: CaptionColorKey) => {\n // Hide highlight / outline pickers entirely when disabled for this style.\n if (key === \"highlight\" && !useHighlight) {\n return null;\n }\n if (key === \"outlineColor\" && !useOutline) {\n return null;\n }\n const label = currentColorMeta.labels[key] ?? defaultColorLabels[key];\n const value = colors[key];\n\n const handleChange = (next: string) => {\n const nextColors = { ...colors, [key]: next };\n setColors(nextColors);\n handleUpdateCaption({ colors: nextColors });\n };\n\n if (value == null) {\n return null;\n }\n\n return (\n <div className=\"color-control\" key={key}>\n <label className=\"label-small\">{label}</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={value}\n onChange={(e) => handleChange(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={value}\n onChange={(e) => handleChange(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n );\n };\n\n return (\n <div className=\"panel-container\">\n {/* Caption Style */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Caption Style</label>\n <select\n value={capStyle.value}\n onChange={(e) => {\n const val = e.target.value as keyof typeof CAPTION_STYLE_OPTIONS;\n if (val in CAPTION_STYLE_OPTIONS) {\n setCapStyle(CAPTION_STYLE_OPTIONS[val]);\n }\n handleUpdateCaption({ style: e.target.value });\n }}\n className=\"select-dark w-full\"\n >\n {Object.values(CAPTION_STYLE_OPTIONS).map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Font Size */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Font Size</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"8\"\n max=\"72\"\n step=\"1\"\n value={fontSize}\n onChange={(e) => {\n const value = Number(e.target.value);\n setFontSize(value);\n handleUpdateCaption({ fontSize: value });\n }}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{fontSize}px</span>\n </div>\n </div>\n\n {/* Font */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Font</label>\n <select\n value={fontFamily}\n onChange={(e) => {\n const value = e.target.value;\n setFontFamily(value);\n handleUpdateCaption({ fontFamily: value });\n }}\n className=\"select-dark w-full\"\n >\n {CAPTION_FONTS.map((font) => (\n <option key={font} value={font}>\n {font}\n </option>\n ))}\n </select>\n </div>\n\n {/* Colors */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Colors</label>\n <div className=\"color-section\">\n {/* Highlight toggle only when style supports highlight color */}\n {currentColorMeta.usedColors.includes(\"highlight\") && (\n <div className=\"checkbox-control\">\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={useHighlight}\n onChange={(e) => {\n const enabled = e.target.checked;\n setUseHighlight(enabled);\n // Keep colors state typed (highlight is always a string in local state),\n // but when highlight is disabled we omit it when writing to timeline data.\n const nextColors = enabled\n ? { ...colors, highlight: colors.highlight || CAPTION_COLOR.highlight }\n : { ...colors };\n setColors(nextColors);\n handleUpdateCaption({\n colors: nextColors,\n useHighlightOverride: enabled,\n });\n }}\n className=\"checkbox-purple\"\n />\n Use Highlight Color\n </label>\n </div>\n )}\n {/* Outline toggle only when style supports outline color */}\n {currentColorMeta.usedColors.includes(\"outlineColor\") && (\n <div className=\"checkbox-control\">\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={useOutline}\n onChange={(e) => {\n const enabled = e.target.checked;\n setUseOutline(enabled);\n const nextColors = enabled\n ? {\n ...colors,\n outlineColor: colors.outlineColor || CAPTION_COLOR.outlineColor,\n }\n : { ...colors };\n setColors(nextColors);\n handleUpdateCaption({\n colors: nextColors,\n useOutlineOverride: enabled,\n });\n }}\n className=\"checkbox-purple\"\n />\n Use Outline Color\n </label>\n </div>\n )}\n {currentColorMeta.usedColors.map((key) => renderColorControl(key))}\n </div>\n </div>\n </div>\n );\n}\n\nexport default CaptionPropPanel;\n","/**\n * Volume conversion between linear (0-1) and dB scale.\n * Used for PlaybackPropsPanel to match professional audio tools (e.g. -60 dB to +6 dB).\n *\n * Formula: dB = 20 * log10(linear)\n * - 0 dB = 1.0 linear (full volume)\n * - -60 dB ≈ 0.001 linear (effectively mute)\n * - +6 dB ≈ 2.0 linear (amplification)\n */\n\nconst MIN_DB = -60;\nconst MAX_DB = 6;\n\n/**\n * Convert linear volume (0 to ~2) to dB.\n * Returns MIN_DB for linear <= 0 to avoid -Infinity.\n */\nexport function linearToDb(linear: number): number {\n if (linear <= 0) return MIN_DB;\n const db = 20 * Math.log10(linear);\n return Math.max(MIN_DB, Math.min(MAX_DB, db));\n}\n\n/**\n * Convert dB to linear volume.\n * Returns 0 for dB <= MIN_DB (mute).\n */\nexport function dbToLinear(db: number): number {\n if (db <= MIN_DB) return 0;\n const linear = Math.pow(10, db / 20);\n return Math.min(linear, Math.pow(10, MAX_DB / 20));\n}\n\nexport { MIN_DB, MAX_DB };\n","import { linearToDb, dbToLinear, MIN_DB, MAX_DB } from \"../../helpers/volume-db\";\nimport type { PropertiesPanelProps } from \"../../types\";\nimport { AccordionItem } from \"../shared/accordion-item\";\nimport { PropertyRow } from \"./property-row\";\nimport { Music2 } from \"lucide-react\";\nimport { useState } from \"react\";\n\nconst PLAYBACK_RATE_MIN = 0.25;\nconst PLAYBACK_RATE_MAX = 2;\nconst PLAYBACK_RATE_STEP = 0.25;\n\nexport function PlaybackPropsPanel({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n const elementProps = selectedElement?.getProps() || {};\n const volumeLinear = elementProps.volume ?? 1;\n const volumeDb = linearToDb(volumeLinear);\n const playbackRate = elementProps.playbackRate ?? 1;\n\n const handleUpdateElement = (props: Record<string, any>) => {\n if (selectedElement) {\n updateElement?.(selectedElement?.setProps({ ...elementProps, ...props }));\n }\n };\n\n const handleVolumeDbChange = (db: number) => {\n handleUpdateElement({ volume: dbToLinear(db) });\n };\n\n const handlePlaybackRateChange = (rate: number) => {\n handleUpdateElement({ playbackRate: rate });\n };\n\n const [isPlaybackOpen, setIsPlaybackOpen] = useState(false);\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Playback</div>\n <AccordionItem\n title=\"Playback\"\n icon={<Music2 className=\"icon-sm\" />}\n isOpen={isPlaybackOpen}\n onToggle={() => setIsPlaybackOpen((open) => !open)}\n >\n <div className=\"properties-group\">\n {/* Playback rate */}\n <div className=\"property-section\">\n <PropertyRow\n label=\"Playback rate\"\n secondary={<span>{playbackRate}×</span>}\n >\n <input\n type=\"range\"\n min={PLAYBACK_RATE_MIN}\n max={PLAYBACK_RATE_MAX}\n step={PLAYBACK_RATE_STEP}\n value={playbackRate}\n onChange={(e) =>\n handlePlaybackRateChange(Number(e.target.value))\n }\n className=\"slider-purple\"\n />\n </PropertyRow>\n </div>\n\n {/* Volume (dB) */}\n <div className=\"property-section\">\n <PropertyRow\n label=\"Volume\"\n secondary={\n <span>\n {volumeDb <= MIN_DB ? \"−∞\" : `${Math.round(volumeDb)} dB`}\n </span>\n }\n >\n <input\n type=\"range\"\n min={MIN_DB}\n max={MAX_DB}\n step={1}\n value={volumeDb}\n onChange={(e) =>\n handleVolumeDbChange(Number(e.target.value))\n }\n className=\"slider-purple\"\n />\n </PropertyRow>\n </div>\n </div>\n </AccordionItem>\n </div>\n );\n}\n","const imageDimensionsCache = {};\nconst videoMetaCache = {};\nconst audioDurationCache = {};\n\nconst getAudioDuration = (audioSrc) => {\n if (audioDurationCache[audioSrc]) {\n return Promise.resolve(audioDurationCache[audioSrc]);\n }\n return new Promise((resolve, reject) => {\n const audio = document.createElement(\"audio\");\n audio.preload = \"metadata\";\n const isSafeUrl = /^(https?:|blob:|data:audio\\/)/i.test(audioSrc);\n if (!isSafeUrl) {\n throw new Error(\"Unsafe audio source URL\");\n }\n audio.src = audioSrc;\n audio.onloadedmetadata = () => {\n const duration = audio.duration;\n audioDurationCache[audioSrc] = duration;\n resolve(duration);\n };\n audio.onerror = () => {\n reject(new Error(\"Failed to load audio metadata\"));\n };\n });\n};\n\nconst concurrencyLimit = 5;\nlet activeCount = 0;\nconst queue = [];\nfunction runNext() {\n if (queue.length === 0 || activeCount >= concurrencyLimit) return;\n const next = queue.shift();\n if (next) {\n activeCount++;\n next();\n }\n}\nfunction limit(fn) {\n return new Promise((resolve, reject) => {\n const task = () => {\n fn().then(resolve).catch(reject).finally(() => {\n activeCount--;\n runNext();\n });\n };\n if (activeCount < concurrencyLimit) {\n activeCount++;\n task();\n } else {\n queue.push(task);\n }\n });\n}\n\nconst loadImageDimensions = (url) => {\n return new Promise((resolve, reject) => {\n if (typeof document === \"undefined\") {\n reject(new Error(\"getImageDimensions() is only available in the browser.\"));\n return;\n }\n const img = new Image();\n img.onload = () => {\n resolve({ width: img.naturalWidth, height: img.naturalHeight });\n };\n img.onerror = reject;\n img.src = url;\n });\n};\nconst getImageDimensions = (url) => {\n if (imageDimensionsCache[url]) {\n return Promise.resolve(imageDimensionsCache[url]);\n }\n return limit(() => loadImageDimensions(url)).then((dimensions) => {\n imageDimensionsCache[url] = dimensions;\n return dimensions;\n });\n};\n\nconst getVideoMeta = (videoSrc) => {\n if (videoMetaCache[videoSrc]) {\n return Promise.resolve(videoMetaCache[videoSrc]);\n }\n return new Promise((resolve, reject) => {\n const isSafeUrl = /^(https?:|blob:|data:video\\/)/i.test(videoSrc);\n if (!isSafeUrl) {\n reject(new Error(\"Unsafe video source URL\"));\n return;\n }\n const tryLoadVideo = (useCors) => {\n const video = document.createElement(\"video\");\n video.preload = \"metadata\";\n video.crossOrigin = useCors ? \"anonymous\" : null;\n video.src = videoSrc;\n video.onloadedmetadata = () => {\n const meta = {\n width: video.videoWidth,\n height: video.videoHeight,\n duration: video.duration\n };\n videoMetaCache[videoSrc] = meta;\n resolve(meta);\n };\n video.onerror = () => {\n if (useCors) {\n video.src = \"\";\n tryLoadVideo(false);\n } else {\n reject(new Error(\"Failed to load video metadata. This may be due to CORS restrictions or an invalid video URL.\"));\n }\n };\n };\n tryLoadVideo(true);\n });\n};\n\nconst getThumbnail = async (videoUrl, seekTime = 0.1, playbackRate = 1) => {\n return new Promise((resolve, reject) => {\n const tryLoadThumbnail = (useCors) => {\n const video = document.createElement(\"video\");\n video.crossOrigin = useCors ? \"anonymous\" : null;\n video.muted = true;\n video.playsInline = true;\n video.autoplay = false;\n video.preload = \"auto\";\n video.playbackRate = playbackRate;\n video.style.position = \"absolute\";\n video.style.left = \"-9999px\";\n video.style.top = \"-9999px\";\n video.style.width = \"1px\";\n video.style.height = \"1px\";\n video.style.opacity = \"0\";\n video.style.pointerEvents = \"none\";\n video.style.zIndex = \"-1\";\n let timeoutId;\n const cleanup = () => {\n if (video.parentNode) video.remove();\n if (timeoutId) clearTimeout(timeoutId);\n };\n const handleError = () => {\n cleanup();\n if (useCors) {\n tryLoadThumbnail(false);\n } else {\n reject(new Error(`Failed to load video: ${video.error?.message || \"Unknown error. This may be due to CORS restrictions or an invalid video URL.\"}`));\n }\n };\n const handleSeeked = () => {\n try {\n video.pause();\n const canvas = document.createElement(\"canvas\");\n const width = video.videoWidth || 640;\n const height = video.videoHeight || 360;\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n cleanup();\n reject(new Error(\"Failed to get canvas context\"));\n return;\n }\n ctx.drawImage(video, 0, 0, width, height);\n try {\n const dataUrl = canvas.toDataURL(\"image/jpeg\", 0.8);\n cleanup();\n resolve(dataUrl);\n } catch {\n canvas.toBlob((blob) => {\n if (!blob) {\n cleanup();\n reject(new Error(\"Failed to create Blob\"));\n return;\n }\n const blobUrl = URL.createObjectURL(blob);\n cleanup();\n resolve(blobUrl);\n }, \"image/jpeg\", 0.8);\n }\n } catch (err) {\n cleanup();\n reject(new Error(`Error creating thumbnail: ${err}`));\n }\n };\n video.addEventListener(\"error\", handleError, { once: true });\n video.addEventListener(\"seeked\", handleSeeked, { once: true });\n video.addEventListener(\"loadedmetadata\", () => {\n const playPromise = video.play();\n if (playPromise !== void 0) {\n playPromise.then(() => {\n video.currentTime = seekTime || 0.1;\n }).catch(() => {\n video.currentTime = seekTime || 0.1;\n });\n } else {\n video.currentTime = seekTime || 0.1;\n }\n }, { once: true });\n timeoutId = window.setTimeout(() => {\n cleanup();\n reject(new Error(\"Video loading timed out\"));\n }, 15e3);\n video.src = videoUrl;\n document.body.appendChild(video);\n };\n tryLoadThumbnail(true);\n });\n};\n\nclass LRUCache {\n constructor(maxSize = 100) {\n if (maxSize <= 0) {\n throw new Error(\"maxSize must be greater than 0\");\n }\n this.maxSize = maxSize;\n this.cache = /* @__PURE__ */ new Map();\n }\n /**\n * Get a value from the cache.\n * Moves the item to the end (most recently used).\n */\n get(key) {\n const value = this.cache.get(key);\n if (value === void 0) {\n return void 0;\n }\n this.cache.delete(key);\n this.cache.set(key, value);\n return value;\n }\n /**\n * Set a value in the cache.\n * If cache is full, removes the least recently used item.\n */\n set(key, value) {\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n if (firstKey !== void 0) {\n this.cache.delete(firstKey);\n }\n }\n this.cache.set(key, value);\n }\n /**\n * Check if a key exists in the cache.\n */\n has(key) {\n return this.cache.has(key);\n }\n /**\n * Delete a key from the cache.\n */\n delete(key) {\n return this.cache.delete(key);\n }\n /**\n * Clear all entries from the cache.\n */\n clear() {\n this.cache.clear();\n }\n /**\n * Get the current size of the cache.\n */\n get size() {\n return this.cache.size;\n }\n}\n\nclass VideoFrameExtractor {\n constructor(options = {}) {\n this.frameCache = new LRUCache(\n options.maxCacheSize ?? 50\n );\n this.videoElements = /* @__PURE__ */ new Map();\n this.maxVideoElements = options.maxVideoElements ?? 5;\n this.loadTimeout = options.loadTimeout ?? 15e3;\n this.jpegQuality = options.jpegQuality ?? 0.8;\n this.playbackRate = options.playbackRate ?? 1;\n }\n /**\n * Get a frame thumbnail from a video at a specific time.\n * Uses caching and reuses video elements for optimal performance.\n * Uses 0.1s instead of 0 when seekTime is 0, since frames at t=0 are often blank.\n *\n * @param videoUrl - The URL of the video\n * @param seekTime - The time in seconds to extract the frame (0 is treated as 0.1)\n * @returns Promise resolving to a thumbnail image URL (data URL or blob URL)\n */\n async getFrame(videoUrl, seekTime = 0.1) {\n const effectiveSeekTime = seekTime === 0 ? 0.1 : seekTime;\n const cacheKey = this.getCacheKey(videoUrl, effectiveSeekTime);\n const cached = this.frameCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n const videoState = await this.getVideoElement(videoUrl);\n const thumbnail = await this.extractFrame(videoState.video, effectiveSeekTime);\n this.frameCache.set(cacheKey, thumbnail);\n return thumbnail;\n }\n /**\n * Get or create a video element for the given URL.\n * Reuses existing elements and manages cleanup.\n */\n async getVideoElement(videoUrl) {\n let videoState = this.videoElements.get(videoUrl);\n if (videoState && videoState.isReady) {\n videoState.lastUsed = Date.now();\n return videoState;\n }\n if (videoState && videoState.isLoading && videoState.loadPromise) {\n await videoState.loadPromise;\n if (videoState.isReady) {\n videoState.lastUsed = Date.now();\n return videoState;\n }\n }\n if (this.videoElements.size >= this.maxVideoElements) {\n this.cleanupOldVideoElements();\n }\n videoState = await this.createVideoElement(videoUrl);\n this.videoElements.set(videoUrl, videoState);\n videoState.lastUsed = Date.now();\n return videoState;\n }\n /**\n * Create and initialize a new video element.\n */\n async createVideoElement(videoUrl) {\n const video = document.createElement(\"video\");\n video.crossOrigin = \"anonymous\";\n video.muted = true;\n video.playsInline = true;\n video.autoplay = false;\n video.preload = \"auto\";\n video.playbackRate = this.playbackRate;\n video.style.position = \"absolute\";\n video.style.left = \"-9999px\";\n video.style.top = \"-9999px\";\n video.style.width = \"1px\";\n video.style.height = \"1px\";\n video.style.opacity = \"0\";\n video.style.pointerEvents = \"none\";\n video.style.zIndex = \"-1\";\n const state = {\n video,\n isReady: false,\n isLoading: true,\n loadPromise: null,\n lastUsed: Date.now()\n };\n state.loadPromise = new Promise((resolve, reject) => {\n let timeoutId;\n const cleanup = () => {\n if (timeoutId) clearTimeout(timeoutId);\n };\n const handleError = () => {\n cleanup();\n state.isLoading = false;\n reject(new Error(`Failed to load video: ${video.error?.message || \"Unknown error\"}`));\n };\n const handleLoadedMetadata = () => {\n cleanup();\n state.isReady = true;\n state.isLoading = false;\n resolve();\n };\n video.addEventListener(\"error\", handleError, { once: true });\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata, { once: true });\n timeoutId = window.setTimeout(() => {\n cleanup();\n state.isLoading = false;\n reject(new Error(\"Video loading timed out\"));\n }, this.loadTimeout);\n video.src = videoUrl;\n document.body.appendChild(video);\n });\n try {\n await state.loadPromise;\n } catch (error) {\n if (video.parentNode) {\n video.remove();\n }\n throw error;\n }\n return state;\n }\n /**\n * Extract a frame from a video at the specified time.\n */\n async extractFrame(video, seekTime) {\n return new Promise((resolve, reject) => {\n video.pause();\n const timeThreshold = 0.1;\n if (Math.abs(video.currentTime - seekTime) < timeThreshold) {\n try {\n const canvas = document.createElement(\"canvas\");\n const width = video.videoWidth || 640;\n const height = video.videoHeight || 360;\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"Failed to get canvas context\"));\n return;\n }\n ctx.drawImage(video, 0, 0, width, height);\n try {\n const dataUrl = canvas.toDataURL(\"image/jpeg\", this.jpegQuality);\n resolve(dataUrl);\n } catch {\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error(\"Failed to create Blob\"));\n return;\n }\n const blobUrl = URL.createObjectURL(blob);\n resolve(blobUrl);\n },\n \"image/jpeg\",\n this.jpegQuality\n );\n }\n return;\n } catch (err) {\n reject(new Error(`Error creating thumbnail: ${err}`));\n return;\n }\n }\n const handleSeeked = () => {\n try {\n const canvas = document.createElement(\"canvas\");\n const width = video.videoWidth || 640;\n const height = video.videoHeight || 360;\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"Failed to get canvas context\"));\n return;\n }\n ctx.drawImage(video, 0, 0, width, height);\n try {\n const dataUrl = canvas.toDataURL(\"image/jpeg\", this.jpegQuality);\n resolve(dataUrl);\n } catch {\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error(\"Failed to create Blob\"));\n return;\n }\n const blobUrl = URL.createObjectURL(blob);\n resolve(blobUrl);\n },\n \"image/jpeg\",\n this.jpegQuality\n );\n }\n } catch (err) {\n reject(new Error(`Error creating thumbnail: ${err}`));\n }\n };\n video.addEventListener(\"seeked\", handleSeeked, { once: true });\n const playPromise = video.play();\n if (playPromise !== void 0) {\n playPromise.then(() => {\n video.currentTime = seekTime;\n }).catch(() => {\n video.currentTime = seekTime;\n });\n } else {\n video.currentTime = seekTime;\n }\n });\n }\n /**\n * Generate cache key for a video URL and seek time.\n */\n getCacheKey(videoUrl, seekTime) {\n const roundedTime = Math.round(seekTime * 100) / 100;\n return `${videoUrl}:${roundedTime}`;\n }\n /**\n * Cleanup least recently used video elements.\n */\n cleanupOldVideoElements() {\n if (this.videoElements.size < this.maxVideoElements) {\n return;\n }\n const entries = Array.from(this.videoElements.entries());\n entries.sort((a, b) => a[1].lastUsed - b[1].lastUsed);\n const toRemove = entries.slice(0, entries.length - this.maxVideoElements + 1);\n for (const [url, state] of toRemove) {\n if (state.video.parentNode) {\n state.video.remove();\n }\n this.videoElements.delete(url);\n }\n }\n /**\n * Clear the frame cache.\n */\n clearCache() {\n this.frameCache.clear();\n }\n /**\n * Remove a specific video element and clear its cached frames.\n */\n removeVideo(videoUrl) {\n const state = this.videoElements.get(videoUrl);\n if (state) {\n if (state.video.parentNode) {\n state.video.remove();\n }\n this.videoElements.delete(videoUrl);\n }\n this.frameCache.clear();\n }\n /**\n * Dispose of all video elements and clear caches.\n * Removes all video elements from the DOM and clears both the frame cache\n * and video element cache. Call this when the extractor is no longer needed\n * to prevent memory leaks.\n */\n dispose() {\n for (const state of this.videoElements.values()) {\n if (state.video.parentNode) {\n state.video.remove();\n }\n }\n this.videoElements.clear();\n this.frameCache.clear();\n }\n}\nlet defaultExtractor = null;\nfunction getDefaultVideoFrameExtractor(options) {\n if (!defaultExtractor) {\n defaultExtractor = new VideoFrameExtractor(options);\n }\n return defaultExtractor;\n}\nasync function getThumbnailCached(videoUrl, seekTime = 0.1, playbackRate) {\n const extractor = getDefaultVideoFrameExtractor(\n playbackRate !== void 0 ? { playbackRate } : void 0\n );\n return extractor.getFrame(videoUrl, seekTime);\n}\n\nconst extractAudio = async ({\n src,\n playbackRate = 1,\n start = 0,\n end\n}) => {\n if (!src) throw new Error(\"src is required\");\n if (playbackRate <= 0) throw new Error(\"playbackRate must be > 0\");\n const isSafeUrl = /^(https?:|blob:|data:)/i.test(src);\n if (!isSafeUrl) throw new Error(\"Unsafe media source URL\");\n const audioBuffer = await fetchAndDecodeAudio(src);\n if (audioBuffer.duration === 0 || audioBuffer.length === 0) {\n throw new Error(\"No audio track found in the media source\");\n }\n if (isAudioSilent(audioBuffer)) {\n throw new Error(\"Audio track is silent (no audio content detected)\");\n }\n const clampedStart = Math.max(0, start || 0);\n const fullDuration = audioBuffer.duration;\n const clampedEnd = Math.min(\n typeof end === \"number\" ? end : fullDuration,\n fullDuration\n );\n if (clampedEnd <= clampedStart)\n throw new Error(\"Invalid range: end must be greater than start\");\n const renderedBuffer = await renderAudioSegment(\n audioBuffer,\n clampedStart,\n clampedEnd,\n playbackRate\n );\n const mp3Blob = await audioBufferToMp3(renderedBuffer);\n return URL.createObjectURL(mp3Blob);\n};\nconst hasAudio = async (src) => {\n if (!src) return false;\n const isSafeUrl = /^(https?:|blob:|data:)/i.test(src);\n if (!isSafeUrl) return false;\n try {\n const audioBuffer = await fetchAndDecodeAudio(src);\n if (audioBuffer.duration === 0 || audioBuffer.length === 0) {\n return false;\n }\n if (isAudioSilent(audioBuffer)) {\n return false;\n }\n return true;\n } catch (error) {\n return false;\n }\n};\nconst stitchAudio = async (segments, totalDuration) => {\n if (!segments || segments.length === 0) {\n throw new Error(\"At least one audio segment is required\");\n }\n const duration = totalDuration || Math.max(...segments.map((s) => s.e));\n const renderedBuffer = await createAudioTimeline(segments, duration);\n const mp3Blob = await audioBufferToMp3(renderedBuffer);\n return URL.createObjectURL(mp3Blob);\n};\nconst fetchAndDecodeAudio = async (src) => {\n const response = await fetch(src);\n if (!response.ok) throw new Error(`Failed to fetch source: ${response.status}`);\n const arrayBuffer = await response.arrayBuffer();\n return decodeAudioData(arrayBuffer);\n};\nconst decodeAudioData = async (arrayBuffer) => {\n const AudioContextCtor = window.AudioContext || window.webkitAudioContext;\n if (!AudioContextCtor) throw new Error(\"Web Audio API not supported\");\n const audioContext = new AudioContextCtor();\n try {\n return await new Promise((resolve, reject) => {\n audioContext.decodeAudioData(\n arrayBuffer.slice(0),\n (buf) => resolve(buf),\n (err) => reject(err || new Error(\"Failed to decode audio: no audio track found or unsupported format\"))\n );\n });\n } finally {\n audioContext.close();\n }\n};\nconst isAudioSilent = (buffer, threshold = 1e-3) => {\n for (let channel = 0; channel < buffer.numberOfChannels; channel++) {\n const channelData = buffer.getChannelData(channel);\n for (let i = 0; i < channelData.length; i += 100) {\n if (Math.abs(channelData[i]) > threshold) {\n return false;\n }\n }\n }\n return true;\n};\nconst renderAudioSegment = async (audioBuffer, start, end, playbackRate) => {\n const OfflineAudioContextCtor = window.OfflineAudioContext || window.webkitOfflineAudioContext;\n if (!OfflineAudioContextCtor) throw new Error(\"OfflineAudioContext not supported\");\n const sampleRate = audioBuffer.sampleRate;\n const numChannels = audioBuffer.numberOfChannels;\n const sourceDuration = end - start;\n const renderedFrames = Math.max(\n 1,\n Math.ceil(sourceDuration / playbackRate * sampleRate)\n );\n const offline = new OfflineAudioContextCtor(numChannels, renderedFrames, sampleRate);\n const sourceNode = offline.createBufferSource();\n sourceNode.buffer = audioBuffer;\n sourceNode.playbackRate.value = playbackRate;\n sourceNode.connect(offline.destination);\n sourceNode.start(0, start, sourceDuration);\n return await offline.startRendering();\n};\nconst createAudioTimeline = async (segments, duration) => {\n const OfflineAudioContextCtor = window.OfflineAudioContext || window.webkitOfflineAudioContext;\n if (!OfflineAudioContextCtor) throw new Error(\"OfflineAudioContext not supported\");\n const sampleRate = 44100;\n const totalFrames = Math.ceil(duration * sampleRate);\n const offline = new OfflineAudioContextCtor(2, totalFrames, sampleRate);\n for (const segment of segments) {\n if (segment.s >= segment.e) continue;\n const volume = segment.volume ?? 1;\n if (volume <= 0) continue;\n try {\n const audioBuffer = await fetchAndDecodeAudio(segment.src);\n const segmentDuration = segment.e - segment.s;\n const sourceDuration = Math.min(segmentDuration, audioBuffer.duration);\n const source = offline.createBufferSource();\n source.buffer = audioBuffer;\n if (volume !== 1) {\n const gainNode = offline.createGain();\n gainNode.gain.value = volume;\n source.connect(gainNode);\n gainNode.connect(offline.destination);\n } else {\n source.connect(offline.destination);\n }\n source.start(segment.s, 0, sourceDuration);\n } catch {\n }\n }\n return await offline.startRendering();\n};\nconst audioBufferToMp3 = async (buffer) => {\n try {\n const wavArrayBuffer = audioBufferToWavArrayBuffer(buffer);\n const pcmBuffer = await decodeAudioData(wavArrayBuffer);\n return await encodePcmToMp3(pcmBuffer);\n } catch (error) {\n return audioBufferToWavBlob(buffer);\n }\n};\nconst audioBufferToWavArrayBuffer = (buffer) => {\n const numChannels = buffer.numberOfChannels;\n const sampleRate = buffer.sampleRate;\n const numFrames = buffer.length;\n const interleaved = interleave(buffer, numChannels, numFrames);\n const bytesPerSample = 2;\n const blockAlign = numChannels * bytesPerSample;\n const byteRate = sampleRate * blockAlign;\n const dataSize = interleaved.length * bytesPerSample;\n const bufferSize = 44 + dataSize;\n const arrayBuffer = new ArrayBuffer(bufferSize);\n const view = new DataView(arrayBuffer);\n writeString(view, 0, \"RIFF\");\n view.setUint32(4, 36 + dataSize, true);\n writeString(view, 8, \"WAVE\");\n writeString(view, 12, \"fmt \");\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n view.setUint16(22, numChannels, true);\n view.setUint32(24, sampleRate, true);\n view.setUint32(28, byteRate, true);\n view.setUint16(32, blockAlign, true);\n view.setUint16(34, 16, true);\n writeString(view, 36, \"data\");\n view.setUint32(40, dataSize, true);\n floatTo16BitPCM(view, 44, interleaved);\n return arrayBuffer;\n};\nconst encodePcmToMp3 = async (buffer) => {\n const lamejs = await import('./index-CXhwwSX-.mjs').then(n => n.i);\n const channels = buffer.numberOfChannels >= 2 ? 2 : 1;\n const targetSampleRate = 22050;\n const downsampledBuffer = downsampleAudioBuffer(buffer, targetSampleRate);\n const kbps = 48;\n const mp3encoder = new lamejs.default.Mp3Encoder(channels, targetSampleRate, kbps);\n const samplesPerFrame = 1152;\n const leftFloat = downsampledBuffer.getChannelData(0);\n const left = floatTo16(leftFloat);\n let right;\n if (channels === 2) {\n const rightFloat = downsampledBuffer.getChannelData(1);\n right = floatTo16(rightFloat);\n }\n const mp3Chunks = [];\n for (let i = 0; i < left.length; i += samplesPerFrame) {\n const leftChunk = left.subarray(i, Math.min(i + samplesPerFrame, left.length));\n let mp3buf;\n if (channels === 2 && right) {\n const rightChunk = right.subarray(i, Math.min(i + samplesPerFrame, right.length));\n mp3buf = mp3encoder.encodeBuffer(leftChunk, rightChunk);\n } else {\n mp3buf = mp3encoder.encodeBuffer(leftChunk);\n }\n if (mp3buf.length > 0) mp3Chunks.push(mp3buf);\n }\n const end = mp3encoder.flush();\n if (end.length > 0) mp3Chunks.push(end);\n return new Blob(mp3Chunks, { type: \"audio/mpeg\" });\n};\nconst audioBufferToWavBlob = (buffer) => {\n const arrayBuffer = audioBufferToWavArrayBuffer(buffer);\n return new Blob([arrayBuffer], { type: \"audio/wav\" });\n};\nconst downsampleAudioBuffer = (buffer, targetSampleRate) => {\n if (buffer.sampleRate === targetSampleRate) {\n return buffer;\n }\n const ratio = buffer.sampleRate / targetSampleRate;\n const newLength = Math.round(buffer.length / ratio);\n const newBuffer = new AudioContext().createBuffer(\n buffer.numberOfChannels,\n newLength,\n targetSampleRate\n );\n for (let channel = 0; channel < buffer.numberOfChannels; channel++) {\n const oldData = buffer.getChannelData(channel);\n const newData = newBuffer.getChannelData(channel);\n for (let i = 0; i < newLength; i++) {\n const oldIndex = Math.floor(i * ratio);\n newData[i] = oldData[oldIndex];\n }\n }\n return newBuffer;\n};\nconst interleave = (buffer, numChannels, numFrames) => {\n if (numChannels === 1) {\n return buffer.getChannelData(0).slice(0, numFrames);\n }\n const result = new Float32Array(numFrames * numChannels);\n const channelData = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channelData[ch] = buffer.getChannelData(ch);\n }\n let writeIndex = 0;\n for (let i = 0; i < numFrames; i++) {\n for (let ch = 0; ch < numChannels; ch++) {\n result[writeIndex++] = channelData[ch][i];\n }\n }\n return result;\n};\nconst floatTo16BitPCM = (view, offset, input) => {\n let pos = offset;\n for (let i = 0; i < input.length; i++, pos += 2) {\n let s = Math.max(-1, Math.min(1, input[i]));\n view.setInt16(pos, s < 0 ? s * 32768 : s * 32767, true);\n }\n};\nconst floatTo16 = (input) => {\n const output = new Int16Array(input.length);\n for (let i = 0; i < input.length; i++) {\n const s = Math.max(-1, Math.min(1, input[i]));\n output[i] = s < 0 ? s * 32768 : s * 32767;\n }\n return output;\n};\nconst writeString = (view, offset, str) => {\n for (let i = 0; i < str.length; i++) {\n view.setUint8(offset + i, str.charCodeAt(i));\n }\n};\n\nconst getScaledDimensions = (width, height, maxWidth, maxHeight) => {\n if (width <= maxWidth && height <= maxHeight) {\n return {\n width: width % 2 === 0 ? width : width - 1,\n height: height % 2 === 0 ? height : height - 1\n };\n }\n const widthRatio = maxWidth / width;\n const heightRatio = maxHeight / height;\n const scale = Math.min(widthRatio, heightRatio);\n let scaledWidth = Math.round(width * scale);\n let scaledHeight = Math.round(height * scale);\n if (scaledWidth % 2 !== 0) {\n scaledWidth -= 1;\n }\n if (scaledHeight % 2 !== 0) {\n scaledHeight -= 1;\n }\n return {\n width: Math.min(scaledWidth, maxWidth),\n height: Math.min(scaledHeight, maxHeight)\n };\n};\nconst getObjectFitSize = (objectFit, elementSize, containerSize) => {\n const elementAspectRatio = elementSize.width / elementSize.height;\n const containerAspectRatio = containerSize.width / containerSize.height;\n switch (objectFit) {\n case \"contain\":\n if (elementAspectRatio > containerAspectRatio) {\n return {\n width: containerSize.width,\n height: containerSize.width / elementAspectRatio\n };\n } else {\n return {\n width: containerSize.height * elementAspectRatio,\n height: containerSize.height\n };\n }\n case \"cover\":\n if (elementAspectRatio > containerAspectRatio) {\n return {\n width: containerSize.height * elementAspectRatio,\n height: containerSize.height\n };\n } else {\n return {\n width: containerSize.width,\n height: containerSize.width / elementAspectRatio\n };\n }\n case \"fill\":\n return {\n width: containerSize.width,\n height: containerSize.height\n };\n default:\n return {\n width: elementSize.width,\n height: elementSize.height\n };\n }\n};\n\nconst blobUrlToFile = async (blobUrl, fileName) => {\n const response = await fetch(blobUrl);\n const blob = await response.blob();\n return new File([blob], fileName, { type: blob.type });\n};\nconst loadFile = (accept) => {\n return new Promise((resolve, reject) => {\n try {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = accept;\n input.style.display = \"none\";\n document.body.appendChild(input);\n const cleanup = () => {\n input.value = \"\";\n document.body.removeChild(input);\n };\n input.onchange = () => {\n const file = input.files && input.files[0];\n cleanup();\n if (!file) {\n reject(new Error(\"No file selected\"));\n return;\n }\n resolve(file);\n };\n input.click();\n } catch (error) {\n reject(error);\n }\n });\n};\nconst saveAsFile = (content, type, name) => {\n const blob = typeof content === \"string\" ? new Blob([content], { type }) : content;\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = name;\n a.click();\n URL.revokeObjectURL(url);\n};\nconst downloadFile = async (url, filename) => {\n try {\n const response = await fetch(url);\n const blob = await response.blob();\n const downloadUrl = window.URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = downloadUrl;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n window.URL.revokeObjectURL(downloadUrl);\n } catch (error) {\n throw error;\n }\n};\n\nconst detectMediaTypeFromUrl = async (url) => {\n try {\n const response = await fetch(url, { method: \"HEAD\" });\n const contentType = response.headers.get(\"Content-Type\");\n if (!contentType) return null;\n if (contentType.startsWith(\"image/\")) return \"image\";\n if (contentType.startsWith(\"video/\")) return \"video\";\n if (contentType.startsWith(\"audio/\")) return \"audio\";\n return null;\n } catch {\n return null;\n }\n};\n\nexport { VideoFrameExtractor, blobUrlToFile, detectMediaTypeFromUrl, downloadFile, extractAudio, getAudioDuration, getDefaultVideoFrameExtractor, getImageDimensions, getObjectFitSize, getScaledDimensions, getThumbnail, getThumbnailCached, getVideoMeta, hasAudio, limit, loadFile, saveAsFile, stitchAudio };\n//# sourceMappingURL=index.mjs.map\n","import { TrackElement, VideoElement } from \"@twick/timeline\";\nimport { useEffect, useState, useRef } from \"react\";\nimport { hasAudio } from \"@twick/media-utils\";\nimport { Loader2, VolumeX, Volume2, CheckCircle2, XCircle } from \"lucide-react\";\nimport {\n CaptionPhraseLength,\n ICaptionGenerationPollingResponse,\n} from \"../../types\";\n\nexport function GenerateCaptionsPanel({\n selectedElement,\n addCaptionsToTimeline,\n onGenerateCaptions,\n getCaptionstatus,\n pollingIntervalMs = 5000,\n}: {\n selectedElement: TrackElement;\n addCaptionsToTimeline: (\n captions: { s: number; e: number; t: string; w?: number[] }[]\n ) => void;\n onGenerateCaptions: (\n videoElement: VideoElement,\n language?: string,\n phraseLength?: CaptionPhraseLength,\n ) => Promise<string | null>;\n getCaptionstatus: (reqId: string) => Promise<ICaptionGenerationPollingResponse>;\n pollingIntervalMs?: number;\n}) {\n const [containsAudio, setContainsAudio] = useState<boolean | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [isGenerating, setIsGenerating] = useState(false);\n const [pollingStatus, setPollingStatus] = useState<\"idle\" | \"polling\" | \"success\" | \"error\">(\"idle\");\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const [selectedLanguage, setSelectedLanguage] = useState<string>(\"auto\");\n const [phraseLength, setPhraseLength] =\n useState<CaptionPhraseLength>(\"medium\");\n const pollingIntervalRef = useRef<NodeJS.Timeout | null>(null);\n const currentReqIdRef = useRef<string | null>(null);\n\n // Cleanup polling on unmount\n useEffect(() => {\n return () => {\n if (pollingIntervalRef.current) {\n clearInterval(pollingIntervalRef.current);\n }\n };\n }, []);\n\n const stopPolling = () => {\n if (pollingIntervalRef.current) {\n clearInterval(pollingIntervalRef.current);\n pollingIntervalRef.current = null;\n }\n };\n\n const startPolling = async (reqId: string) => {\n if (!getCaptionstatus) {\n return;\n }\n setPollingStatus(\"polling\");\n setIsGenerating(true);\n setErrorMessage(null);\n\n const poll = async () => {\n try {\n const response = await getCaptionstatus(reqId);\n\n \n if (response.status === \"completed\") {\n stopPolling();\n setPollingStatus(\"success\");\n setIsGenerating(false);\n \n // Add captions to timeline\n addCaptionsToTimeline(response.captions || []);\n \n // Reset status after 3 seconds\n setTimeout(() => {\n setPollingStatus(\"idle\");\n }, 3000);\n } else if (response.status === \"pending\") {\n // Continue polling - interval will call this again\n } else if (response.status === \"failed\") {\n stopPolling();\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(response.error || \"Failed to generate captions\");\n console.error(\"Error generating captions:\", response.error);\n }\n } catch (error) {\n stopPolling();\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(error instanceof Error ? error.message : \"Failed to get caption status\");\n console.error(\"Error polling for captions:\", error);\n }\n };\n\n // Poll immediately, then at configured interval (default 5 seconds)\n await poll();\n pollingIntervalRef.current = setInterval(poll, pollingIntervalMs);\n };\n\n const handleGenerateCaptions = async () => {\n if (!(selectedElement instanceof VideoElement)) {\n return;\n }\n\n setIsGenerating(true);\n setPollingStatus(\"polling\");\n const videoElement = selectedElement as VideoElement;\n \n\n try {\n const language =\n selectedLanguage === \"auto\" ? undefined : selectedLanguage;\n const reqId = await onGenerateCaptions(\n videoElement,\n language,\n phraseLength,\n );\n if (!reqId) {\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(\"Failed to start caption generation\");\n console.error(\"Error generating captions: Failed to start caption generation\");\n return;\n }\n currentReqIdRef.current = reqId;\n await startPolling(reqId);\n } catch (error) {\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(error instanceof Error ? error.message : \"Failed to start caption generation\");\n console.error(\"Error generating captions:\", error);\n }\n };\n\n const checkAudio = async () => {\n setIsLoading(true);\n if (selectedElement instanceof VideoElement) {\n const videoElement = selectedElement as VideoElement;\n const videoUrl = videoElement.getSrc();\n if (videoUrl) {\n try {\n const hasAudioTrack = await hasAudio(videoUrl);\n setContainsAudio(hasAudioTrack);\n } catch (error) {\n console.error(\"Error checking audio:\", error);\n setContainsAudio(false);\n }\n } else {\n setContainsAudio(false);\n }\n } else {\n setContainsAudio(false);\n }\n setIsLoading(false);\n };\n\n useEffect(() => {\n checkAudio();\n // Reset polling state when element changes\n stopPolling();\n setPollingStatus(\"idle\");\n setIsGenerating(false);\n setErrorMessage(null);\n }, [selectedElement]);\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Generate Captions Panel</div>\n \n {/* Loading State */}\n {isLoading && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Loader2 className=\"empty-state-icon animate-spin\" />\n <p className=\"empty-state-text\">Checking for audio...</p>\n </div>\n </div>\n </div>\n )}\n\n {/* No Audio State */}\n {!isLoading && containsAudio === false && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <VolumeX className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">No audio track found in this video</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Audio Present State */}\n {!isLoading && containsAudio === true && pollingStatus === \"idle\" && !isGenerating && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Volume2 className=\"empty-state-icon\" />\n <p className=\"empty-state-text\">Audio detected! You can now generate captions</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Language selection */}\n {!isLoading && containsAudio === true && (\n <div className=\"panel-section\">\n <label className=\"label-dark\" htmlFor=\"caption-language\">\n Audio Language\n </label>\n <select\n id=\"caption-language\"\n className=\"select-dark\"\n value={selectedLanguage}\n onChange={(e) => setSelectedLanguage(e.target.value)}\n >\n <option value=\"auto\">Auto (detect)</option>\n <option value=\"english\">English</option>\n <option value=\"italian\">Italian</option>\n <option value=\"spanish\">Spanish</option>\n <option value=\"portuguese\">Portuguese</option>\n <option value=\"french\">French</option>\n <option value=\"german\">German</option>\n <option value=\"turkish\">Turkish</option>\n <option value=\"indonesian\">Indonesian</option>\n <option value=\"hindi\">Hindi</option>\n </select>\n </div>\n )}\n {/* Caption length selection */}\n {!isLoading && containsAudio === true && (\n <div className=\"panel-section\">\n <label className=\"label-dark\" htmlFor=\"caption-phrase-length\">\n Caption length\n </label>\n <select\n id=\"caption-phrase-length\"\n className=\"select-dark\"\n value={phraseLength}\n onChange={(e) =>\n setPhraseLength(e.target.value as CaptionPhraseLength)\n }\n >\n <option value=\"short\">Short</option>\n <option value=\"medium\">Medium</option>\n <option value=\"long\">Long</option>\n </select>\n </div>\n )}\n\n {/* Polling/Generating State */}\n {!isLoading && isGenerating && pollingStatus === \"polling\" && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <Loader2 className=\"empty-state-icon animate-spin\" />\n <p className=\"empty-state-text\">Generating captions... Please wait</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Success State */}\n {!isLoading && pollingStatus === \"success\" && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <CheckCircle2 className=\"empty-state-icon\" color=\"var(--color-green-500)\" />\n <p className=\"empty-state-text\">Captions generated successfully!</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Error State */}\n {!isLoading && pollingStatus === \"error\" && (\n <div className=\"panel-section\">\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <XCircle className=\"empty-state-icon\" color=\"var(--color-red-500)\" />\n <p className=\"empty-state-text\">{errorMessage || \"Failed to generate captions\"}</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Generate Button */}\n {!isLoading && (\n <div className=\"flex panel-section\">\n <button\n onClick={handleGenerateCaptions}\n disabled={!containsAudio || isGenerating}\n className=\"btn-primary w-full\"\n >\n {isGenerating ? \"Generating...\" : \"Generate Captions\"}\n </button>\n </div>\n )}\n </div>\n );\n}\n","import { TextElement } from \"@twick/timeline\";\nimport type { PropertiesPanelProps } from \"../../types\";\nimport { AccordionItem } from \"../shared/accordion-item\";\nimport { PropertyRow } from \"./property-row\";\nimport { Type, AlignLeft, AlignCenter, AlignRight, Bold, Italic } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport function TextPropsPanel({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n if (!(selectedElement instanceof TextElement)) return null;\n\n const textProps = selectedElement.getProps() || {};\n\n const [isTypographyOpen, setIsTypographyOpen] = useState(false);\n\n const currentAlign = textProps.textAlign ?? \"center\";\n const currentWeight = textProps.fontWeight ?? 400;\n const isBold = currentWeight >= 600;\n const isItalic = textProps.fontStyle === \"italic\";\n\n const handleUpdate = (patch: Partial<typeof textProps>) => {\n if (!selectedElement) return;\n const next = { ...textProps, ...patch };\n selectedElement.setProps(next);\n updateElement?.(selectedElement);\n };\n\n const toggleBold = () => {\n handleUpdate({ fontWeight: isBold ? 400 : 700 });\n };\n\n const toggleItalic = () => {\n handleUpdate({ fontStyle: isItalic ? \"normal\" : \"italic\" });\n };\n\n const setAlign = (align: \"left\" | \"center\" | \"right\") => {\n handleUpdate({ textAlign: align });\n };\n\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Typography</div>\n <AccordionItem\n title=\"Typography\"\n icon={<Type className=\"icon-sm\" />}\n isOpen={isTypographyOpen}\n onToggle={() => setIsTypographyOpen((open) => !open)}\n >\n <div className=\"properties-group\">\n {/* Font size */}\n <div className=\"property-section\">\n <PropertyRow\n label=\"Font size\"\n secondary={<span>{textProps.fontSize ?? 48}px</span>}\n >\n <input\n type=\"range\"\n min={8}\n max={160}\n value={textProps.fontSize ?? 48}\n onChange={(e) =>\n handleUpdate({ fontSize: Number(e.target.value) })\n }\n className=\"slider-purple\"\n />\n </PropertyRow>\n </div>\n\n {/* Style: bold / italic */}\n <div className=\"property-section\">\n <PropertyRow label=\"Style\">\n <button\n type=\"button\"\n className={`form-btn ${isBold ? \"active\" : \"\"}`}\n onClick={toggleBold}\n title=\"Bold\"\n >\n <Bold className=\"icon-sm\" />\n </button>\n <button\n type=\"button\"\n className={`form-btn ${isItalic ? \"active\" : \"\"}`}\n onClick={toggleItalic}\n title=\"Italic\"\n >\n <Italic className=\"icon-sm\" />\n </button>\n </PropertyRow>\n </div>\n\n {/* Alignment */}\n <div className=\"property-section\">\n <PropertyRow label=\"Align\">\n <button\n type=\"button\"\n className={`form-btn ${currentAlign === \"left\" ? \"active\" : \"\"}`}\n onClick={() => setAlign(\"left\")}\n title=\"Align left\"\n >\n <AlignLeft className=\"icon-sm\" />\n </button>\n <button\n type=\"button\"\n className={`form-btn ${\n currentAlign === \"center\" ? \"active\" : \"\"\n }`}\n onClick={() => setAlign(\"center\")}\n title=\"Align center\"\n >\n <AlignCenter className=\"icon-sm\" />\n </button>\n <button\n type=\"button\"\n className={`form-btn ${\n currentAlign === \"right\" ? \"active\" : \"\"\n }`}\n onClick={() => setAlign(\"right\")}\n title=\"Align right\"\n >\n <AlignRight className=\"icon-sm\" />\n </button>\n </PropertyRow>\n </div>\n\n </div>\n </AccordionItem>\n </div>\n );\n}\n\n","import { useEffect, useState } from \"react\";\nimport {\n ArrowElement,\n LineElement,\n RectElement,\n CircleElement,\n type TrackElement,\n} from \"@twick/timeline\";\nimport { Palette } from \"lucide-react\";\nimport { AccordionItem } from \"../shared/accordion-item\";\nimport type { PropertiesPanelProps } from \"../../types\";\n\n/** Parse fill to hex for color input; supports #hex and rgba(). */\nfunction fillToHex(fill: string | undefined): string {\n if (!fill) return \"#f59e0b\";\n if (fill.startsWith(\"#\")) return fill.slice(0, 7);\n const rgba = fill.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n if (rgba) {\n const r = Number(rgba[1]).toString(16).padStart(2, \"0\");\n const g = Number(rgba[2]).toString(16).padStart(2, \"0\");\n const b = Number(rgba[3]).toString(16).padStart(2, \"0\");\n return `#${r}${g}${b}`;\n }\n return \"#f59e0b\";\n}\n\ntype ShapeElement = ArrowElement | LineElement | RectElement | CircleElement;\n\nfunction isShapeElement(\n el: TrackElement | null | undefined\n): el is ShapeElement {\n return (\n el != null &&\n (el instanceof ArrowElement ||\n el instanceof LineElement ||\n el instanceof RectElement ||\n el instanceof CircleElement)\n );\n}\n\nexport function AnnotationStylePanel({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n const [styleOpen, setStyleOpen] = useState(true);\n const [fill, setFill] = useState(\"#f59e0b\");\n const [opacity, setOpacity] = useState(1);\n const [radius, setRadius] = useState<number | null>(null);\n const [thickness, setThickness] = useState<number | null>(null);\n\n const shape = isShapeElement(selectedElement) ? selectedElement : null;\n\n useEffect(() => {\n if (!shape) return;\n\n const props = shape.getProps();\n // Resolve fill\n const currentFill =\n props?.fill ??\n (shape instanceof RectElement || shape instanceof CircleElement\n ? shape.getFill()\n : undefined);\n setFill(fillToHex(currentFill));\n\n // Opacity\n setOpacity(shape.getOpacity() ?? 1);\n\n // Radius / thickness defaults by type\n if (shape instanceof RectElement) {\n setRadius(shape.getCornerRadius());\n setThickness(null);\n } else if (shape instanceof CircleElement) {\n setRadius(shape.getRadius());\n setThickness(null);\n } else if (shape instanceof LineElement) {\n setThickness(props?.height ?? 4);\n setRadius(props?.radius ?? 4);\n } else if (shape instanceof ArrowElement) {\n setRadius(props?.radius ?? 4);\n setThickness(null);\n }\n }, [shape, selectedElement?.getId()]);\n\n const handleFillChange = (value: string) => {\n if (!shape) return;\n setFill(value);\n const props = shape.getProps();\n\n if (shape instanceof RectElement || shape instanceof CircleElement) {\n shape.setFill(value);\n } else {\n shape.setProps({ ...props, fill: value });\n }\n\n updateElement?.(shape);\n };\n\n const handleOpacityChange = (value: number) => {\n if (!shape) return;\n setOpacity(value);\n shape.setOpacity(value);\n updateElement?.(shape);\n };\n\n const handleRadiusChange = (value: number) => {\n if (!shape) return;\n setRadius(value);\n if (shape instanceof RectElement) {\n shape.setCornerRadius(value);\n } else if (shape instanceof CircleElement) {\n shape.setRadius(value);\n } else {\n const props = shape.getProps();\n shape.setProps({ ...props, radius: value });\n }\n updateElement?.(shape);\n };\n\n const handleThicknessChange = (value: number) => {\n if (!shape || !(shape instanceof LineElement)) return;\n setThickness(value);\n const props = shape.getProps();\n shape.setProps({ ...props, height: value, lineWidth: value });\n updateElement?.(shape);\n };\n\n if (!shape) return null;\n\n return (\n <div className=\"panel-container\">\n <AccordionItem\n title=\"Shape style\"\n icon={<Palette className=\"icon-sm\" />}\n isOpen={styleOpen}\n onToggle={() => setStyleOpen((open) => !open)}\n >\n <div className=\"properties-group\">\n <div className=\"panel-section\">\n <label className=\"label-dark\">Color</label>\n <div className=\"color-control\">\n <label className=\"label-small\">Fill</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={fill}\n onChange={(e) => handleFillChange(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={fill}\n onChange={(e) => handleFillChange(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n </div>\n <div className=\"panel-section\">\n <label className=\"label-dark\">Opacity</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n step=\"1\"\n value={Math.round(opacity * 100)}\n onChange={(e) =>\n handleOpacityChange(Number(e.target.value) / 100)\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{Math.round(opacity * 100)}%</span>\n </div>\n </div>\n\n {/* Radius for box/circle/arrow/line (where applicable) */}\n {radius !== null && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">\n {shape instanceof CircleElement ? \"Radius (size)\" : \"Corner radius\"}\n </label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"200\"\n step=\"1\"\n value={radius}\n onChange={(e) => handleRadiusChange(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{Math.round(radius)}</span>\n </div>\n </div>\n )}\n\n {/* Thickness for line */}\n {thickness !== null && shape instanceof LineElement && (\n <div className=\"panel-section\">\n <label className=\"label-dark\">Thickness</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"1\"\n max=\"40\"\n step=\"1\"\n value={thickness}\n onChange={(e) =>\n handleThicknessChange(Number(e.target.value))\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">\n {Math.round(thickness)} px\n </span>\n </div>\n </div>\n )}\n </div>\n </AccordionItem>\n </div>\n );\n}\n","import { ElementProps } from \"../properties/element-props\";\nimport { TextEffects } from \"../properties/text-effects\";\nimport { Animation } from \"../properties/animation\";\nimport {\n VideoElement,\n TextElement,\n AudioElement,\n CaptionElement,\n ArrowElement,\n LineElement,\n RectElement,\n CircleElement,\n type TrackElement,\n Size,\n useTimelineContext,\n} from \"@twick/timeline\";\nimport { CaptionPropPanel } from \"../properties/caption-prop\";\nimport { PlaybackPropsPanel } from \"../properties/playback-props\";\nimport { GenerateCaptionsPanel } from \"../properties/generate-captions.tsx\";\nimport { TextPropsPanel } from \"../properties/text-props\";\nimport { AnnotationStylePanel } from \"../properties/annotation-style-panel\";\nimport { ICaptionGenerationPollingResponse, CaptionEntry } from \"../../types\";\nimport { useCallback } from \"react\";\n\nconst DEFAULT_CANVAS_BACKGROUND = \"#000000\";\n\ninterface PropertiesPanelContainerProps {\n selectedElement: TrackElement | null;\n updateElement: (element: TrackElement) => void;\n addCaptionsToTimeline: (captions: CaptionEntry[]) => void;\n onGenerateCaptions: (videoElement: VideoElement) => Promise<string | null>;\n getCaptionstatus: (reqId: string) => Promise<ICaptionGenerationPollingResponse>;\n pollingIntervalMs: number;\n videoResolution: Size;\n}\n\nexport function PropertiesPanelContainer({\n selectedElement,\n updateElement,\n addCaptionsToTimeline,\n onGenerateCaptions,\n getCaptionstatus,\n pollingIntervalMs,\n videoResolution,\n}: PropertiesPanelContainerProps) {\n const { editor, present } = useTimelineContext();\n const backgroundColor =\n present?.backgroundColor ??\n editor.getBackgroundColor() ??\n DEFAULT_CANVAS_BACKGROUND;\n\n const handleBackgroundColorChange = useCallback(\n (value: string) => {\n editor.setBackgroundColor(value);\n },\n [editor]\n );\n\n const annotationTitle =\n selectedElement instanceof ArrowElement\n ? \"Arrow callout\"\n : selectedElement instanceof LineElement\n ? \"Line\"\n : selectedElement instanceof RectElement\n ? \"Box\"\n : selectedElement instanceof CircleElement\n ? \"Circle\"\n : null;\n const title = annotationTitle\n ?? (selectedElement instanceof TextElement ? selectedElement.getText() : null)\n ?? selectedElement?.getName()\n ?? selectedElement?.getType()\n ?? \"Element\";\n\n return (\n <aside className=\"properties-panel\" aria-label=\"Element properties inspector\">\n <div className=\"properties-header\">\n {!selectedElement && (\n <h3 className=\"properties-title\">Composition</h3>\n )}\n {selectedElement && selectedElement.getType() === \"caption\" && (\n <h3 className=\"properties-title\">Caption</h3>\n )}\n {selectedElement && selectedElement.getType() !== \"caption\" && (\n <h3 className=\"properties-title\">\n {title}\n </h3>\n )}\n </div>\n\n <div className=\"prop-content\">\n {/* Composition inspector when nothing selected */}\n {!selectedElement && (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Canvas & Render</div>\n <div className=\"properties-group\">\n <div className=\"property-section\">\n <span className=\"property-label\">Size</span>\n <span className=\"properties-size-readonly\">\n {videoResolution.width} × {videoResolution.height}\n </span>\n </div>\n <div className=\"color-control\">\n <label className=\"label-small\">Background Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={backgroundColor}\n onChange={(e) =>\n handleBackgroundColorChange(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={backgroundColor}\n onChange={(e) =>\n handleBackgroundColorChange(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* Caption inspector when caption is selected */}\n {selectedElement instanceof CaptionElement && (\n <>\n <CaptionPropPanel\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n </>\n )}\n\n {/* Element inspector when non-caption is selected */}\n {selectedElement && !(selectedElement instanceof CaptionElement) && (\n <>\n {(() => {\n const isText = selectedElement instanceof TextElement;\n const isVideo = selectedElement instanceof VideoElement;\n const isAudio = selectedElement instanceof AudioElement;\n\n const isAnnotation =\n selectedElement instanceof ArrowElement ||\n selectedElement instanceof LineElement ||\n selectedElement instanceof RectElement ||\n selectedElement instanceof CircleElement;\n\n return (\n <>\n {/* Typography (Text only) */}\n {isText && (\n <TextPropsPanel\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Transform – visual elements only (not audio) */}\n {!isAudio && (\n <ElementProps\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Annotation style – color & opacity (arrow, highlight, blur) */}\n {isAnnotation && (\n <AnnotationStylePanel\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Playback + Volume – video and audio */}\n {(isVideo || isAudio) && (\n <PlaybackPropsPanel\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Text Effects – text only */}\n {isText && (\n <TextEffects\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Animations – visual elements only (not audio) */}\n {!isAudio && (\n <Animation\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Generate Captions – video only */}\n {isVideo && (\n <GenerateCaptionsPanel\n selectedElement={selectedElement}\n addCaptionsToTimeline={addCaptionsToTimeline}\n onGenerateCaptions={onGenerateCaptions}\n getCaptionstatus={getCaptionstatus}\n pollingIntervalMs={pollingIntervalMs}\n />\n )}\n </>\n );\n })()}\n </>\n )}\n </div>\n </aside>\n );\n}\n","import {\n PLAYER_STATE,\n ProjectJSON,\n exportChaptersAsJSON,\n exportChaptersAsYouTube,\n exportCaptionsAsSRT,\n exportCaptionsAsVTT,\n getCaptionLanguages,\n useTimelineContext,\n} from \"@twick/timeline\";\nimport { ICaptionGenerationPollingResponse, StudioConfig, CaptionEntry } from \"../types\";\nimport { loadFile, saveAsFile } from \"@twick/media-utils\";\nimport { useState } from \"react\";\nimport { useLivePlayerContext } from \"@twick/live-player\";\n\nconst useStudioOperation = (studioConfig?: StudioConfig) => {\n const { editor, present, videoResolution } = useTimelineContext();\n const { setSeekTime, setPlayerState } = useLivePlayerContext();\n const [projectName, setProjectName] = useState(\"\");\n\n const onNewProject = () => {\n setPlayerState(PLAYER_STATE.PAUSED);\n editor.loadProject({\n tracks: [],\n version: 0,\n });\n setSeekTime(0);\n }\n\n const onLoadProject = async () => {\n let project: ProjectJSON;\n setPlayerState(PLAYER_STATE.PAUSED);\n if (studioConfig?.loadProject) {\n project = await studioConfig.loadProject();\n } else {\n const file = await loadFile(\"application/json\");\n const text = await file.text();\n setProjectName(file.name);\n project = JSON.parse(text);\n }\n editor.loadProject(project);\n setSeekTime(0.01);\n };\n\n const onSaveProject = async () => {\n let fileName;\n if (projectName) {\n fileName = projectName;\n } else {\n fileName = prompt(\"Enter the name of the project\") || \"untitled-project\";\n fileName = fileName + \".json\";\n setProjectName(fileName);\n }\n if (studioConfig?.saveProject && present) {\n await studioConfig.saveProject(present, fileName);\n } else {\n const file = await saveAsFile(\n JSON.stringify(present),\n \"application/json\",\n fileName\n );\n if (file) {\n console.log(\"File saved\", file);\n }\n }\n };\n\n const onExportVideo = async () => {\n if (studioConfig?.exportVideo && present) {\n await studioConfig.exportVideo(present, {\n outFile: \"output.mp4\",\n fps: 30,\n resolution: {\n width: videoResolution.width,\n height: videoResolution.height,\n },\n });\n } else {\n alert(\"Export video not supported in demo mode\");\n }\n };\n\n const onExportCaptions = async (format: \"srt\" | \"vtt\") => {\n if (!present) return;\n const baseName = (projectName || \"captions\").replace(/\\.json$/i, \"\");\n const languages = getCaptionLanguages(present);\n\n if (languages.length <= 1) {\n const content =\n format === \"srt\"\n ? exportCaptionsAsSRT(present, languages[0])\n : exportCaptionsAsVTT(present, languages[0]);\n await saveAsFile(content, \"text/plain\", `${baseName}.${format}`);\n return;\n }\n\n for (const language of languages) {\n const content =\n format === \"srt\"\n ? exportCaptionsAsSRT(present, language)\n : exportCaptionsAsVTT(present, language);\n await saveAsFile(content, \"text/plain\", `${baseName}.${language}.${format}`);\n }\n };\n\n const onExportChapters = async (format: \"youtube\" | \"json\") => {\n if (!present) return;\n const content =\n format === \"youtube\"\n ? exportChaptersAsYouTube(present)\n : exportChaptersAsJSON(present);\n const fileName = `${(projectName || \"chapters\").replace(/\\.json$/i, \"\")}.${\n format === \"youtube\" ? \"txt\" : \"json\"\n }`;\n await saveAsFile(content, \"text/plain\", fileName);\n };\n\n const addCaptionsToTimeline = (captions: CaptionEntry[]) => {\n const updatedProjectJSON = studioConfig?.captionGenerationService?.updateProjectWithCaptions(captions);\n if (updatedProjectJSON) {\n editor.loadProject(updatedProjectJSON);\n }\n }\n\n const getCaptionstatus = async (reqId: string) => {\n if (studioConfig?.captionGenerationService) {\n const service = studioConfig.captionGenerationService;\n return await service.getRequestStatus(reqId);\n }\n return {\n status: \"failed\",\n error: \"Caption generation service not found\",\n } as ICaptionGenerationPollingResponse;\n }\n\n return { \n onLoadProject, \n onSaveProject, \n onExportVideo, \n onNewProject,\n onExportCaptions,\n onExportChapters,\n addCaptionsToTimeline,\n getCaptionstatus,\n };\n};\n\nexport default useStudioOperation;\n","/**\n * TwickStudio Component\n *\n * The main studio component that provides a complete video editing interface.\n * Integrates all major components including canvas, toolbar, media library,\n * and properties panel into a cohesive editing environment.\n *\n * @component\n * @example\n * ```tsx\n * <LivePlayerProvider>\n * <TimelineProvider initialData={initialData} contextId=\"studio-demo\">\n * <TwickStudio />\n * </TimelineProvider>\n * </LivePlayerProvider>\n * ```\n */\n\nimport { Toolbar } from \"./toolbar\";\nimport StudioHeader from \"./header\";\nimport { useStudioManager } from \"../hooks/use-studio-manager\";\nimport ElementPanelContainer from \"./container/element-panel-container\";\nimport { useTimelineContext } from \"@twick/timeline\";\nimport { MediaProvider } from \"../context/media-context\";\nimport { PropertiesPanelContainer } from \"./container/properties-panel-container\";\nimport VideoEditor from \"@twick/video-editor\";\nimport { useMemo } from \"react\";\nimport { StudioConfig } from \"../types\";\nimport useStudioOperation from \"../hooks/use-studio-operation\";\nimport { useGenerateCaptions } from \"..\";\n\nexport function TwickStudio({ studioConfig }: { studioConfig?: StudioConfig }) {\n const {\n selectedTool,\n setSelectedTool,\n selectedElement,\n addElement,\n updateElement,\n } = useStudioManager();\n const { editor, present, videoResolution, setVideoResolution } =\n useTimelineContext();\n const {\n onNewProject,\n onLoadProject,\n onSaveProject,\n onExportVideo,\n onExportCaptions,\n onExportChapters,\n } = useStudioOperation(studioConfig);\n\n const {\n onGenerateCaptions,\n addCaptionsToTimeline,\n getCaptionstatus,\n pollingIntervalMs,\n } = useGenerateCaptions(studioConfig);\n\n const twickStudiConfig: StudioConfig = useMemo(\n () => ({\n canvasMode: true,\n ...(studioConfig || {}),\n videoProps: {\n ...(studioConfig?.videoProps || {}),\n width: videoResolution.width,\n height: videoResolution.height,\n backgroundColor:\n present?.backgroundColor ??\n editor.getBackgroundColor() ??\n studioConfig?.videoProps?.backgroundColor,\n },\n }),\n [videoResolution, studioConfig, present?.backgroundColor, editor]\n );\n\n return (\n <MediaProvider>\n <div className=\"studio-container\">\n {/* Header */}\n <StudioHeader\n setVideoResolution={setVideoResolution}\n onNewProject={onNewProject}\n onLoadProject={onLoadProject}\n onSaveProject={onSaveProject}\n onExportVideo={onExportVideo}\n onExportCaptions={onExportCaptions}\n onExportChapters={onExportChapters}\n />\n {/* Main Content */}\n <div className=\"studio-content\">\n {/* Left Toolbar */}\n <Toolbar\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n customTools={twickStudiConfig.customTools}\n hiddenTools={twickStudiConfig.hiddenTools}\n />\n\n {/* Left Panel (Element Library) */}\n <div className=\"studio-left-panel\">\n <ElementPanelContainer\n videoResolution={videoResolution}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n selectedElement={selectedElement}\n addElement={addElement}\n updateElement={updateElement}\n uploadConfig={twickStudiConfig.uploadConfig}\n studioConfig={twickStudiConfig}\n />\n </div>\n\n {/* Center - Canvas and Transport */}\n <main className=\"main-container\">\n <div className=\"canvas-wrapper\">\n <div\n className=\"canvas-container\"\n style={{\n maxWidth: twickStudiConfig.playerProps?.maxWidth ?? \"100%\",\n }}\n >\n <VideoEditor editorConfig={twickStudiConfig} />\n </div>\n </div>\n </main>\n\n {/* Right Panel (Inspector + Props Toolbar) */}\n <div className=\"studio-right-panel\">\n <PropertiesPanelContainer\n selectedElement={selectedElement}\n updateElement={updateElement}\n addCaptionsToTimeline={addCaptionsToTimeline}\n onGenerateCaptions={onGenerateCaptions}\n getCaptionstatus={getCaptionstatus}\n pollingIntervalMs={pollingIntervalMs}\n videoResolution={videoResolution}\n />\n </div>\n </div>\n </div>\n </MediaProvider>\n );\n}\n","import { ProjectJSON, useTimelineContext, VideoElement } from \"@twick/timeline\";\nimport {\n ICaptionGenerationPollingResponse,\n StudioConfig,\n CaptionEntry,\n CaptionPhraseLength,\n} from \"../types\";\n\nconst useGenerateCaptions = (studioConfig?: StudioConfig) => {\n const { editor, present } = useTimelineContext();\n /**\n * Generates captions using the new polling-based service\n * Returns a function that can be called to start the generation process\n */\n const onGenerateCaptions = async (\n videoElement: VideoElement,\n language?: string,\n phraseLength?: CaptionPhraseLength,\n ) => {\n // Use new polling-based service if available\n if (studioConfig?.captionGenerationService) {\n const service = studioConfig.captionGenerationService;\n const reqId = await service.generateCaptions(\n videoElement,\n present as ProjectJSON,\n language,\n phraseLength,\n );\n return reqId;\n }\n alert(\"Generate captions not supported in demo mode\");\n return null;\n };\n\n const addCaptionsToTimeline = (captions: CaptionEntry[]) => {\n const updatedProjectJSON =\n studioConfig?.captionGenerationService?.updateProjectWithCaptions(\n captions\n );\n if (updatedProjectJSON) {\n editor.loadProject(updatedProjectJSON);\n }\n };\n\n const getCaptionstatus = async (reqId: string) => {\n if (studioConfig?.captionGenerationService) {\n const service = studioConfig.captionGenerationService;\n return await service.getRequestStatus(reqId);\n }\n return {\n status: \"failed\",\n error: \"Caption generation service not found\",\n } as ICaptionGenerationPollingResponse;\n };\n\n const pollingIntervalMs =\n studioConfig?.captionGenerationService?.pollingIntervalMs ?? 5000;\n\n return {\n onGenerateCaptions,\n addCaptionsToTimeline,\n getCaptionstatus,\n pollingIntervalMs,\n };\n};\n\nexport default useGenerateCaptions;\n","/**\n * CirclePanel Component\n *\n * A panel for creating and editing circle shapes in the studio. Provides controls\n * for adjusting radius, fill color, opacity, stroke color, and line width.\n *\n * @component\n * @param {Object} props\n * @param {number} props.radius - Circle radius in pixels\n * @param {string} props.fillColor - Fill color in hex format\n * @param {string} props.strokeColor - Stroke color in hex format\n * @param {number} props.lineWidth - Stroke width in pixels\n * @param {(radius: number) => void} props.setRadius - Update circle radius\n * @param {(color: string) => void} props.setFillColor - Update fill color\n * @param {(opacity: number) => void} props.setOpacity - Update opacity\n * @param {(color: string) => void} props.setStrokeColor - Update stroke color\n * @param {(width: number) => void} props.setLineWidth - Update line width\n * @param {() => void} props.handleApplyChanges - Apply circle element changes\n *\n * @example\n * ```tsx\n * <CirclePanel\n * radius={50}\n * fillColor=\"#ff0000\"\n * opacity={100}\n * strokeColor=\"#000000\"\n * lineWidth={2}\n * setRadius={setRadius}\n * setFillColor={setFill}\n * setOpacity={setOpacity}\n * setStrokeColor={setStroke}\n * setLineWidth={setWidth}\n * handleApplyChanges={applyChanges}\n * />\n * ```\n */\n\nimport type {\n CirclePanelState,\n CirclePanelActions,\n} from \"../../hooks/use-circle-panel\";\n\nexport type CirclePanelProps = CirclePanelState & CirclePanelActions;\n\nexport function CirclePanel({\n radius,\n fillColor,\n strokeColor,\n lineWidth,\n operation,\n setRadius,\n setFillColor,\n setStrokeColor,\n setLineWidth,\n handleApplyChanges,\n}: CirclePanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Circle</div>\n {/* Radius */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Radius</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"10\"\n max=\"300\"\n value={radius}\n onChange={(e) => setRadius(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{radius}px</span>\n </div>\n </div>\n\n {/* Fill Color */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Fill Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={fillColor}\n onChange={(e) => setFillColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={fillColor}\n onChange={(e) => setFillColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n\n {/* Stroke Color */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Stroke Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n {/* Line Width */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Line Width</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"20\"\n value={lineWidth}\n onChange={(e) => setLineWidth(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{lineWidth}px</span>\n </div>\n </div>\n\n {/* Operation button (only for creation, not edits) */}\n {operation !== \"Apply Changes\" && (\n <div className=\"flex panel-section\">\n <button onClick={handleApplyChanges} className=\"btn-primary w-full\">\n {operation}\n </button>\n </div>\n )}\n </div>\n );\n}\n","/**\n * RectPanel Component\n * \n * A panel for creating and editing rectangle shapes in the studio. Provides controls\n * for adjusting corner radius, fill color, opacity, stroke color, and line width.\n * \n * @component\n * @param {Object} props\n * @param {number} props.cornerRadius - Corner radius in pixels\n * @param {string} props.fillColor - Fill color in hex format\n * @param {string} props.strokeColor - Stroke color in hex format\n * @param {number} props.lineWidth - Stroke width in pixels\n * @param {(radius: number) => void} props.setCornerRadius - Update corner radius\n * @param {(color: string) => void} props.setFillColor - Update fill color\n * @param {(opacity: number) => void} props.setOpacity - Update opacity\n * @param {(color: string) => void} props.setStrokeColor - Update stroke color\n * @param {(width: number) => void} props.setLineWidth - Update line width\n * @param {() => void} props.handleApplyChanges - Apply rectangle element changes\n * \n * @example\n * ```tsx\n * <RectPanel\n * cornerRadius={10}\n * fillColor=\"#ff0000\"\n * opacity={100}\n * strokeColor=\"#000000\"\n * lineWidth={2}\n * setCornerRadius={setRadius}\n * setFillColor={setFill}\n * setOpacity={setOpacity}\n * setStrokeColor={setStroke}\n * setLineWidth={setWidth}\n * handleApplyChanges={applyChanges}\n * />\n * ```\n */\n\nimport type { RectPanelState, RectPanelActions } from \"../../hooks/use-rect-panel\";\n\nexport type RectPanelProps = RectPanelState & RectPanelActions;\n\nexport function RectPanel({\n cornerRadius,\n fillColor,\n strokeColor,\n lineWidth,\n operation,\n setCornerRadius,\n setFillColor,\n setStrokeColor,\n setLineWidth,\n handleApplyChanges,\n}: RectPanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Rectangle</div>\n {/* Corner Radius */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Corner Radius</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n value={cornerRadius}\n onChange={(e) => setCornerRadius(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{cornerRadius}px</span>\n </div>\n </div>\n\n {/* Fill Color */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Fill Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={fillColor}\n onChange={(e) => setFillColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={fillColor}\n onChange={(e) => setFillColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n {/* Stroke Color */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Stroke Color</label>\n <div className=\"color-inputs\">\n <input\n type=\"color\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-picker\"\n />\n <input\n type=\"text\"\n value={strokeColor}\n onChange={(e) => setStrokeColor(e.target.value)}\n className=\"color-text\"\n />\n </div>\n </div>\n\n {/* Line Width */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Line Width</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"20\"\n value={lineWidth}\n onChange={(e) => setLineWidth(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{lineWidth}px</span>\n </div>\n </div>\n\n {/* Operation button (only for creation, not edits) */}\n {operation !== \"Apply Changes\" && (\n <div className=\"flex panel-section\">\n <button\n onClick={handleApplyChanges}\n className=\"btn-primary w-full\"\n >\n {operation}\n </button>\n </div>\n )}\n </div>\n );\n}","import type { StudioConfig } from \"../types\";\nimport { DEFAULT_PROJECT_TEMPLATES } from \"../templates/default-templates\";\n\nconst sharedVideoProps = {\n width: 720,\n height: 1280,\n};\n\nexport const DEFAULT_STUDIO_CONFIG: StudioConfig = {\n videoProps: sharedVideoProps,\n templates: DEFAULT_PROJECT_TEMPLATES,\n};\n\nexport const EDU_STUDIO_CONFIG: StudioConfig = {\n ...DEFAULT_STUDIO_CONFIG,\n hiddenTools: [\"circle\", \"rect\", \"generate-media\"],\n templates: DEFAULT_PROJECT_TEMPLATES.filter(\n (template) => template.category === \"edu\" || template.category === \"blank\"\n ),\n};\n\nexport const DEMO_STUDIO_CONFIG: StudioConfig = {\n ...DEFAULT_STUDIO_CONFIG,\n hiddenTools: [\"circle\", \"rect\"],\n templates: DEFAULT_PROJECT_TEMPLATES.filter(\n (template) => template.category === \"demo\" || template.category === \"blank\"\n ),\n};\n\nexport const MARKETING_STUDIO_CONFIG: StudioConfig = {\n ...DEFAULT_STUDIO_CONFIG,\n hiddenTools: [],\n templates: DEFAULT_PROJECT_TEMPLATES,\n};\n","import type { ProjectJSON } from \"@twick/timeline\";\nimport {\n exportCaptionsAsSRT,\n exportCaptionsAsVTT,\n exportChaptersAsJSON,\n getCaptionLanguages,\n} from \"@twick/timeline\";\n\nexport interface ProjectBundleExport {\n project: ProjectJSON;\n metadata: ProjectJSON[\"metadata\"];\n chaptersJson: string;\n captions: Array<{\n language: string;\n srt: string;\n vtt: string;\n }>;\n video?: {\n url?: string;\n fileName?: string;\n };\n}\n\nexport interface ExportProjectBundleOptions {\n videoUrl?: string;\n outFile?: string;\n}\n\n/**\n * Creates a portable export bundle with project JSON, chapters, and captions.\n * This intentionally avoids zip dependencies; callers can zip externally.\n */\nexport function exportProjectBundle(\n project: ProjectJSON,\n options?: ExportProjectBundleOptions\n): ProjectBundleExport {\n const languages = getCaptionLanguages(project);\n const captions = (languages.length ? languages : [\"default\"]).map((language) => ({\n language,\n srt: exportCaptionsAsSRT(project, language),\n vtt: exportCaptionsAsVTT(project, language),\n }));\n\n return {\n project,\n metadata: project.metadata,\n chaptersJson: exportChaptersAsJSON(project),\n captions,\n video: {\n url: options?.videoUrl,\n fileName: options?.outFile,\n },\n };\n}\n"],"names":["forwardRef","createElement","__iconNode","Wand2","Icon","jsxs","jsx","useState","useEffect","orientation","useTimelineContext","useEditorManager","TrackElement","useRef","Track","useCallback","BrowserMediaManager","createContext","useContext","VideoElement","AudioElement","ImageElement","config","TIMELINE_DROP_MEDIA_TYPE","Fragment","useMemo","throttle","AVAILABLE_TEXT_FONTS","TextElement","TIMELINE_ELEMENT_TYPE","EffectElement","gl","computeCaptionGeometry","CAPTION_STYLE","CaptionElement","useLivePlayerContext","prompt","TRACK_TYPES","LineElement","ArrowElement","RectElement","CircleElement","_a","rotation","opacity","ElementTextEffect","TEXT_EFFECTS","SparklesIcon","ANIMATIONS","ElementAnimation","CAPTION_STYLE_OPTIONS","Loader2","CheckCircle2","XCircle","PLAYER_STATE","getCaptionLanguages","exportCaptionsAsSRT","exportCaptionsAsVTT","exportChaptersAsYouTube","exportChaptersAsJSON"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40]}
|