@twick/studio 0.14.20 → 0.15.0

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/shared/src/utils.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/defaultAttributes.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/Icon.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/createLucideIcon.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/captions.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/circle-check.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/circle-x.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/circle.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/clapperboard.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/download.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/file.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/image.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/infinity.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/loader-circle.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/message-square.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/music.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/pause.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/play.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/plus.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/save.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/scissors.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/search.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/settings.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/sparkles.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/square.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/trash-2.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/type.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/upload.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/video.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/volume-2.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/volume-x.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/wand-sparkles.js","../../../node_modules/.pnpm/lucide-react@0.511.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/zap.js","../src/components/toolbar.tsx","../src/components/header.tsx","../src/hooks/use-studio-manager.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/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/shared/search-input.tsx","../src/components/panel/icon-panel.tsx","../src/hooks/use-icon-panel.ts","../src/components/container/icon-panel-container.tsx","../src/components/panel/rect-panel.tsx","../src/hooks/use-rect-panel.ts","../src/components/container/rect-panel-container.tsx","../src/components/panel/circle-panel.tsx","../src/hooks/use-circle-panel.ts","../src/components/container/circle-panel-container.tsx","../src/components/panel/subtitles-panel.tsx","../src/helpers/constant.ts","../src/hooks/use-subtitles-panel.ts","../src/components/container/subtitles-panel-container.tsx","../src/components/container/element-panel-container.tsx","../src/components/props-toolbar.tsx","../src/components/properties/element-props.tsx","../src/components/properties/text-effects.tsx","../src/components/properties/animation.tsx","../src/components/properties/playback-props.tsx","../../media-utils/dist/index.mjs","../src/components/properties/generate-subtitles.tsx","../src/components/container/properties-panel-container.tsx","../src/hooks/use-studio-operation.ts","../src/hooks/use-generate-subtitles.ts","../src/components/twick-studio.tsx"],"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 [\"rect\", { width: \"18\", height: \"14\", x: \"3\", y: \"5\", rx: \"2\", ry: \"2\", key: \"12ruh7\" }],\n [\"path\", { d: \"M7 15h4M15 15h2M7 11h2M13 11h4\", key: \"1ueiar\" }]\n];\nconst Captions = createLucideIcon(\"captions\", __iconNode);\n\nexport { __iconNode, Captions as default };\n//# sourceMappingURL=captions.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 [\"path\", { d: \"M6 16c5 0 7-8 12-8a4 4 0 0 1 0 8c-5 0-7-8-12-8a4 4 0 1 0 0 8\", key: \"18ogeb\" }]\n];\nconst Infinity = createLucideIcon(\"infinity\", __iconNode);\n\nexport { __iconNode, Infinity as default };\n//# sourceMappingURL=infinity.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 [\"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 [\"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 [\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: \"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\",\n key: \"1qme2f\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n];\nconst Settings = createLucideIcon(\"settings\", __iconNode);\n\nexport { __iconNode, Settings as default };\n//# sourceMappingURL=settings.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 * @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: \"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z\",\n key: \"1xq2db\"\n }\n ]\n];\nconst Zap = createLucideIcon(\"zap\", __iconNode);\n\nexport { __iconNode, Zap as default };\n//# sourceMappingURL=zap.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 Infinity, \n MessageSquare,\n Plus,\n Square,\n} from 'lucide-react'\nimport type { ToolCategory } from '../types'\n\nconst toolCategories: ToolCategory[] = [\n { id: 'video', name: 'Video', icon: 'Video', description: 'Video' },\n { id: 'image', name: 'Image', icon: 'Image', description: 'Image' },\n { id: 'audio', name: 'Audio', icon: 'Audio', description: 'Audio' },\n { id: 'text', name: 'Text', icon: 'Type', description: 'Add text elements', shortcut: 'T' },\n { id: 'icon', name: 'Icons', icon: 'Icon', description: 'Icon Element', shortcut: 'I' },\n { id: 'circle', name: 'Circle', icon: 'Circle', description: 'Circle Element', shortcut: 'C' },\n { id: 'rect', name: 'Rect', icon: 'Rect', description: 'Rect Element' },\n { id: 'subtitle', name: 'Subtitles', icon: 'MessageSquare', description: 'Manage subtitles', shortcut: 'S' },\n]\n\nconst getIcon = (iconName: string) => {\n switch (iconName) {\n case 'Plus': return Plus\n case 'Type': return Type\n case 'Icon': return Infinity\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 default: return Plus\n }\n}\n\nexport function Toolbar({ selectedTool, setSelectedTool }: { selectedTool: string, setSelectedTool: (tool: string) => void }) {\n\n const handleToolSelect = (toolId: string) => {\n setSelectedTool(toolId)\n }\n\n return (\n <div className=\"sidebar\">\n {/* Main Tools */}\n {toolCategories.map((tool) => {\n const Icon = getIcon(tool.icon)\n const isSelected = selectedTool === tool.id\n \n return (\n <div\n key={tool.id}\n onClick={() => handleToolSelect(tool.id)}\n className={`toolbar-btn ${isSelected ? 'active' : ''}`}\n title={`${tool.name}${tool.shortcut ? ` (${tool.shortcut})` : ''}`}\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 } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\n\ninterface StudioHeaderProps {\n setVideoResolution: (resolution: Size) => void;\n onLoadProject: () => void;\n onSaveProject: () => void;\n onExportVideo: () => void;\n}\nexport const StudioHeader = ({\n setVideoResolution,\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 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 <div className=\"flex-container\">\n <Clapperboard className=\"icon-lg accent-purple\" />\n <h1 className=\"text-gradient\">\n Twick Studio\n </h1>\n </div>\n </div>\n <div className=\"flex-container\">\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-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\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\n // const addSubtitlesToTimeline = (elements: TrackElement[]) => {\n // if (selectedItem instanceof Track && selectedItem.getType() == \"caption\") {\n // elements.forEach((element) => {\n // editor.addElementToTrack(selectedItem, element);\n // });\n // } else {\n // const newTrack = editor.addTrack(\"Track\", \"caption\");\n // elements.forEach((element) => {\n // editor.addElementToTrack(newTrack, element);\n // });\n // }\n // };\n\n useEffect(() => {\n if (selectedItem instanceof TrackElement) {\n setSelectedTool(selectedItem.getType());\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 { 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 // Reset the promise on error so initialization can be retried\n MediaManagerSingleton.initializationPromise = null;\n console.error(\"Error initializing default media:\", error);\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 console.log(`Added ${finalVideosToAdd.length} default video(s) to media library`);\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 console.log(`Added ${finalImagesToAdd.length} default image(s) to media library`);\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 console.log(`Added ${finalAudiosToAdd.length} default audio file(s) to media library`);\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 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}: 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 {/* Upload */}\n {/* <div className=\"flex panel-section\">\n <FileInput\n id=\"audio-upload\"\n acceptFileTypes={acceptFileTypes}\n onFileLoad={onFileUpload}\n buttonText=\"Import media\"\n className=\"btn-primary w-full\"\n icon={<Upload className=\"icon-sm\" />}\n />\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 onDoubleClick={() => onItemSelect(item)}\n className=\"media-list-item\"\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 </div>\n </div>\n );\n};","import { 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 } from \"../shared\";\n\nexport const AudioPanelContainer = (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(\"audio\", {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution);\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 return (\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 * 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 type { ImagePanelProps } from \"../../types/media-panel\";\nimport UrlInput from \"../shared/url-input\";\n\nexport function ImagePanel({\n items,\n onItemSelect,\n onUrlAdd,\n}: ImagePanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Image Library</div>\n\n {/* Add by URL */}\n <div className=\"panel-section\">\n <UrlInput type=\"image\" onSubmit={onUrlAdd} />\n </div>\n {/* Upload */}\n {/* <div className=\"flex panel-section\">\n <FileInput\n id=\"image-upload\"\n acceptFileTypes={acceptFileTypes}\n onFileLoad={onFileUpload}\n buttonText=\"Import media\"\n className=\"btn-primary w-full\"\n icon={<Upload className=\"icon-sm\" />}\n />\n </div> */}\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 onDoubleClick={() => onItemSelect(item)}\n className=\"media-item\"\n >\n <img src={item.url} alt=\"\" className=\"media-item-content\" />\n\n {/* Quick Actions */}\n <div className=\"media-actions\">\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 </div>\n </div>\n );\n}\n","import 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 } from \"../shared\";\n\nexport function ImagePanelContainer(props: PanelProps) {\n const { addItem } = useMedia(\"image\");\n const mediaManager = getMediaManager();\n const {\n items,\n searchQuery,\n setSearchQuery,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes,\n } = useMediaPanel(\"image\", {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution);\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 return (\n <ImagePanel\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","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 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}: 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 <div className=\"flex panel-section\">\n <UrlInput type=\"video\" onSubmit={onUrlAdd} />\n </div>\n\n {/* Import Button */}\n {/* <div className=\"flex panel-section\">\n <FileInput\n id=\"video-upload\"\n acceptFileTypes={acceptFileTypes}\n onFileLoad={onFileUpload}\n buttonText=\"Import media\"\n className=\"btn-primary w-full\"\n icon={<Upload className=\"icon-sm\" />}\n />\n </div> */}\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 onDoubleClick={() => onItemSelect(item)}\n className=\"media-item\"\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 {/* Quick Actions */}\n <div className=\"media-actions\">\n {/* Play/Pause button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n const videoEl = 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\n {/* 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 videos found</p>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n}","import 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 } from \"../shared\";\n\nexport function VideoPanelContainer(props: PanelProps) {\n const { addItem } = useMedia(\"video\");\n const mediaManager = getMediaManager();\n const {\n items,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes,\n } = useMediaPanel(\"video\", {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution);\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 return (\n <VideoPanel\n items={items}\n onItemSelect={handleSelection}\n onFileUpload={handleFileUpload}\n isLoading={isLoading}\n acceptFileTypes={acceptFileTypes}\n onUrlAdd={onUrlAdd}\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 {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 {() => 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 fonts,\n operation,\n setTextContent,\n setFontSize,\n setSelectedFont,\n setIsBold,\n setIsItalic,\n setTextColor,\n setStrokeColor,\n setApplyShadow,\n setShadowColor,\n setStrokeWidth,\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 {/* Operation button */}\n <div className=\"flex panel-section\">\n <button onClick={handleApplyChanges} className=\"btn-primary w-full\">\n {operation}\n </button>\n </div>\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 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 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\n const fonts = Object.values(AVAILABLE_TEXT_FONTS);\n\n const handleApplyChanges = async () => {\n let textElement;\n if (selectedElement instanceof TextElement) {\n textElement = selectedElement;\n textElement.setText(textContent);\n textElement.setFontSize(fontSize);\n textElement.setFontFamily(selectedFont);\n textElement.setFontWeight(isBold ? 700 : 400);\n textElement.setFontStyle(isItalic ? \"italic\" : \"normal\");\n textElement.setFill(textColor);\n textElement.setStrokeColor(strokeColor);\n textElement.setLineWidth(strokeWidth);\n textElement.setTextAlign(DEFAULT_TEXT_PROPS.textAlign);\n if (applyShadow) {\n textElement.setProps({\n ...textElement.getProps(),\n shadowColor,\n shadowOffset: DEFAULT_TEXT_PROPS.shadowOffset,\n shadowBlur: DEFAULT_TEXT_PROPS.shadowBlur,\n shadowOpacity: DEFAULT_TEXT_PROPS.shadowOpacity,\n });\n } else {\n textElement.setProps({\n ...textElement.getProps(),\n shadowColor: undefined,\n shadowOffset: undefined,\n shadowBlur: undefined,\n shadowOpacity: undefined,\n });\n }\n updateElement(textElement);\n } else {\n 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 if (applyShadow) {\n textElement.setProps({\n ...textElement.getProps(),\n shadowColor,\n shadowOffset: DEFAULT_TEXT_PROPS.shadowOffset,\n shadowBlur: DEFAULT_TEXT_PROPS.shadowBlur,\n shadowOpacity: DEFAULT_TEXT_PROPS.shadowOpacity,\n });\n }\n await addElement(textElement);\n }\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 } 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 }\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,\n setFontSize,\n setSelectedFont,\n setIsBold,\n setIsItalic,\n setTextColor,\n setStrokeColor,\n setApplyShadow,\n setShadowColor,\n setStrokeWidth,\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 { 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","/**\n * IconPanel Component\n *\n * A panel for browsing, searching, and adding icons to the studio timeline.\n * Features a searchable grid of SVG icons with preview, add, and download actions.\n * Supports infinite scrolling with \"Load More\" functionality.\n *\n * @component\n * @param {Object} props\n * @param {Icon[]} props.icons - List of icons to display\n * @param {boolean} props.loading - Loading state indicator\n * @param {boolean} props.hasMore - Whether more icons can be loaded\n * @param {number} props.totalIcons - Total number of available icons\n * @param {string} props.searchQuery - Current search query\n * @param {(query: string) => void} props.handleSearch - Handle search query changes\n * @param {(icon: Icon) => void} props.handleSelection - Handle icon selection\n * @param {(icon: Icon) => void} props.handleDownloadIcon - Handle icon download\n * @param {() => void} props.handleLoadMore - Load more icons\n *\n * @example\n * ```tsx\n * <IconPanel\n * icons={icons}\n * loading={false}\n * hasMore={true}\n * totalIcons={1000}\n * searchQuery=\"\"\n * handleSearch={setSearchQuery}\n * handleSelection={addIconToTimeline}\n * handleDownloadIcon={downloadSvg}\n * handleLoadMore={loadNextPage}\n * />\n * ```\n */\n\nimport { Loader2, Download, Plus } from \"lucide-react\";\nimport type {\n IconPanelState,\n IconPanelActions,\n Icon,\n} from \"../../hooks/use-icon-panel\";\nimport SearchInput from \"../shared/search-input\";\n\nexport type IconPanelProps = IconPanelState & IconPanelActions;\n\nexport function IconPanel({\n icons,\n loading,\n totalIcons,\n searchQuery,\n handleSearch,\n handleSelection,\n handleDownloadIcon,\n handleLoadMore,\n}: IconPanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Icon Library</div>\n\n {/* Search */}\n <div className=\"flex panel-section\">\n <SearchInput searchQuery={searchQuery} setSearchQuery={handleSearch} />\n </div>\n\n {/* Icons Grid */}\n <div className=\"media-content\">\n {/* Results Count */}\n {totalIcons > 0 && (\n <div className=\"media-count\">\n Showing {icons.length} of {totalIcons} icons\n </div>\n )}\n\n {/* Loading State */}\n {loading && icons.length === 0 ? (\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\">Loading icons...</p>\n </div>\n </div>\n ) : (\n <div className=\"icon-grid\">\n {(icons || []).map((icon: Icon, index: number) => (\n <div key={index} className=\"icon-item\">\n <div\n onClick={() => handleSelection(icon)}\n className=\"icon-content\"\n dangerouslySetInnerHTML={{ __html: icon.svg }}\n />\n\n {/* Quick Actions */}\n <div className=\"icon-actions\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n handleSelection(icon);\n }}\n className=\"icon-action-btn\"\n title=\"Add to timeline\"\n >\n <Plus className=\"icon-sm\" />\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n handleDownloadIcon(icon);\n }}\n className=\"icon-action-btn\"\n title=\"Download SVG\"\n >\n <Download className=\"icon-sm\" />\n </button>\n </div>\n\n {/* Icon name */}\n <div className=\"icon-name\">{icon.name}</div>\n </div>\n ))}\n </div>\n )}\n\n {/* Empty State */}\n {!loading && icons.length === 0 && searchQuery && (\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <p className=\"empty-state-text\">No icons found</p>\n <p className=\"empty-state-subtext\">Try a different search term</p>\n </div>\n </div>\n )}\n\n {!loading && totalIcons && icons.length < totalIcons && (\n <div className=\"flex panel-section\">\n <button\n onClick={handleLoadMore}\n disabled={loading}\n className=\"btn-primary\"\n >\n Load More Icons\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useState, useRef, useEffect } from \"react\";\nimport { IconElement, TrackElement } from \"@twick/timeline\";\n\nexport interface Icon {\n name: string;\n svg: string;\n}\n\nexport interface IconPanelState {\n icons: Icon[];\n loading: boolean;\n hasMore: boolean;\n totalIcons: number;\n searchQuery: string;\n}\n\nexport interface IconPanelActions {\n handleSearch: (query: string) => void;\n handleSelection: (icon: Icon) => void;\n handleDownloadIcon: (icon: Icon) => void;\n handleLoadMore: () => void;\n}\n\nconst ICONS_PER_PAGE = 20;\n\nexport const useIconPanel = ({\n selectedElement,\n addElement,\n updateElement,\n}: {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}): IconPanelState & IconPanelActions => {\n const [icons, setIcons] = useState<Icon[]>([]);\n const [loading, setLoading] = useState(false);\n const [page, setPage] = useState(1);\n const [hasMore, setHasMore] = useState(true);\n const [totalIcons, setTotalIcons] = useState(0);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const currentQuery = useRef(\"\");\n\n const fetchIcons = async (query: string, reset = false) => {\n try {\n setLoading(true);\n const newPage = reset ? 1 : page;\n const start = (newPage - 1) * ICONS_PER_PAGE;\n const url = `https://api.iconify.design/search?query=${query}&limit=${ICONS_PER_PAGE}&offset=${start}`;\n\n const response = await fetch(url);\n const data = await response.json();\n\n const iconData = data.icons || [];\n const total = data.total || 0;\n setTotalIcons(total);\n\n const formattedIcons = await Promise.all(\n iconData.map(async (icon: any) => {\n const svgUrl = `https://api.iconify.design/${icon}.svg`;\n\n try {\n const svgResponse = await fetch(svgUrl);\n const svg = await svgResponse.text();\n return { name: icon, svg };\n } catch (e) {\n console.error(`Error fetching SVG for ${icon}:`, e);\n return null;\n }\n })\n );\n\n const validIcons = formattedIcons.filter((icon) => icon !== null) as Icon[];\n\n if (reset) {\n setIcons(validIcons);\n } else {\n setIcons([...icons, ...validIcons]);\n }\n\n setHasMore(start + validIcons.length < total);\n if (!reset) {\n setPage(newPage + 1);\n } else {\n setPage(2);\n }\n } catch (error) {\n console.error(\"Error fetching icons:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n fetchIcons(\"media\", true);\n }, []);\n\n const handleSearch = (query: string) => {\n currentQuery.current = query;\n setSearchQuery(query);\n fetchIcons(query, true);\n };\n\n const handleSelection = (icon: Icon) => {\n const svgBlob = new Blob([icon.svg], { type: \"image/svg+xml\" });\n const url = URL.createObjectURL(svgBlob);\n\n let iconElement;\n if (selectedElement instanceof IconElement) {\n iconElement = selectedElement;\n iconElement.setSrc(url);\n iconElement.setName(icon.name);\n updateElement?.(iconElement);\n } else {\n iconElement = new IconElement(url, {\n width: 100,\n height: 100,\n });\n iconElement.setName(icon.name);\n addElement?.(iconElement);\n }\n\n URL.revokeObjectURL(url);\n };\n\n const handleDownloadIcon = (icon: Icon) => {\n const blob = new Blob([icon.svg], { type: \"image/svg+xml\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `${icon.name}.svg`;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n };\n\n const handleLoadMore = () => {\n fetchIcons(currentQuery.current, false);\n };\n\n return {\n icons,\n loading,\n hasMore,\n totalIcons,\n searchQuery,\n handleSearch,\n handleSelection,\n handleDownloadIcon,\n handleLoadMore,\n };\n};\n","import type { PanelProps } from \"../../types\";\nimport { IconPanel } from \"../panel/icon-panel\";\nimport { useIconPanel } from \"../../hooks/use-icon-panel\";\n\nexport function IconPanelContainer(props: PanelProps) {\n const iconPanelProps = useIconPanel({\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n });\n return <IconPanel {...iconPanelProps} />;\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 {number} props.opacity - Opacity percentage (0-100)\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 opacity,\n strokeColor,\n lineWidth,\n operation,\n setCornerRadius,\n setFillColor,\n setOpacity,\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 {/* Opacity */}\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 value={opacity}\n onChange={(e) => setOpacity(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{opacity}%</span>\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 */}\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 </div>\n );\n}","import { useEffect, useState } from \"react\";\nimport { RectElement, TrackElement } from \"@twick/timeline\";\n\nexport const DEFAULT_RECT_PROPS = {\n cornerRadius: 0,\n fillColor: \"#3b82f6\",\n opacity: 100,\n strokeColor: \"#000000\",\n lineWidth: 0,\n};\n\nexport interface RectPanelState {\n cornerRadius: number;\n fillColor: string;\n opacity: number;\n strokeColor: string;\n lineWidth: number;\n operation: string;\n}\n\nexport interface RectPanelActions {\n setCornerRadius: (radius: number) => void;\n setFillColor: (color: string) => void;\n setOpacity: (opacity: number) => void;\n setStrokeColor: (color: string) => void;\n setLineWidth: (width: number) => void;\n handleApplyChanges: () => void;\n}\n\nexport const useRectPanel = ({\n selectedElement,\n addElement,\n updateElement,\n}: {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}): RectPanelState & RectPanelActions => {\n const [cornerRadius, setCornerRadius] = useState(DEFAULT_RECT_PROPS.cornerRadius);\n const [fillColor, setFillColor] = useState(DEFAULT_RECT_PROPS.fillColor);\n const [opacity, setOpacity] = useState(DEFAULT_RECT_PROPS.opacity);\n const [strokeColor, setStrokeColor] = useState(DEFAULT_RECT_PROPS.strokeColor);\n const [lineWidth, setLineWidth] = useState(DEFAULT_RECT_PROPS.lineWidth);\n\n const handleApplyChanges = () => {\n let rectElement;\n if (selectedElement instanceof RectElement) {\n rectElement = selectedElement;\n rectElement.setCornerRadius(cornerRadius);\n rectElement.setOpacity(opacity);\n rectElement.setStrokeColor(strokeColor);\n rectElement.setLineWidth(lineWidth);\n updateElement?.(rectElement);\n } else {\n rectElement = new RectElement(fillColor, { width: 200, height: 200 })\n .setCornerRadius(cornerRadius)\n .setOpacity(opacity)\n .setStrokeColor(strokeColor)\n .setLineWidth(lineWidth);\n addElement?.(rectElement);\n }\n };\n\n useEffect(() => {\n if (selectedElement instanceof RectElement) {\n setCornerRadius(selectedElement.getCornerRadius() ?? DEFAULT_RECT_PROPS.cornerRadius);\n setFillColor(selectedElement.getFill() ?? DEFAULT_RECT_PROPS.fillColor);\n setOpacity(selectedElement.getOpacity() ?? DEFAULT_RECT_PROPS.opacity);\n setStrokeColor(selectedElement.getStrokeColor() ?? DEFAULT_RECT_PROPS.strokeColor);\n setLineWidth(selectedElement.getLineWidth() ?? DEFAULT_RECT_PROPS.lineWidth);\n }\n }, [selectedElement]);\n\n return {\n cornerRadius,\n fillColor,\n opacity,\n strokeColor,\n lineWidth,\n operation: selectedElement instanceof RectElement ? \"Apply Changes\": \"Add Rectangle\",\n setCornerRadius,\n setFillColor,\n setOpacity,\n setStrokeColor,\n setLineWidth,\n handleApplyChanges,\n };\n};\n","import type { PanelProps } from \"../../types\";\nimport { RectPanel } from \"../panel/rect-panel\";\nimport { useRectPanel } from \"../../hooks/use-rect-panel\";\n\nexport function RectPanelContainer(props: PanelProps) {\n const rectPanelProps = useRectPanel({\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n });\n return <RectPanel {...rectPanelProps} />;\n}\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 {number} props.opacity - Opacity percentage (0-100)\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 opacity,\n strokeColor,\n lineWidth,\n operation,\n setRadius,\n setFillColor,\n setOpacity,\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 {/* Opacity */}\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 value={opacity}\n onChange={(e) => setOpacity(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{opacity}%</span>\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 */}\n <div className=\"flex panel-section\">\n <button onClick={handleApplyChanges} className=\"btn-primary w-full\">\n {operation}\n </button>\n </div>\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { CircleElement, TrackElement } from \"@twick/timeline\";\n\nexport const DEFAULT_CIRCLE_PROPS = {\n radius: 50,\n fillColor: \"#3b82f6\",\n opacity: 100,\n strokeColor: \"#000000\",\n lineWidth: 0,\n};\n\nexport interface CirclePanelState {\n radius: number;\n fillColor: string;\n opacity: number;\n strokeColor: string;\n lineWidth: number;\n operation: string;\n}\n\nexport interface CirclePanelActions {\n setRadius: (radius: number) => void;\n setFillColor: (color: string) => void;\n setOpacity: (opacity: number) => void;\n setStrokeColor: (color: string) => void;\n setLineWidth: (width: number) => void;\n handleApplyChanges: () => void;\n}\n\nexport const useCirclePanel = ({\n selectedElement,\n addElement,\n updateElement,\n}: {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}): CirclePanelState & CirclePanelActions => {\n const [radius, setRadius] = useState(DEFAULT_CIRCLE_PROPS.radius);\n const [fillColor, setFillColor] = useState(DEFAULT_CIRCLE_PROPS.fillColor);\n const [opacity, setOpacity] = useState(DEFAULT_CIRCLE_PROPS.opacity);\n const [strokeColor, setStrokeColor] = useState(DEFAULT_CIRCLE_PROPS.strokeColor);\n const [lineWidth, setLineWidth] = useState(DEFAULT_CIRCLE_PROPS.lineWidth);\n\n const handleApplyChanges = () => {\n let circleElement;\n if (selectedElement instanceof CircleElement) {\n circleElement = selectedElement;\n circleElement.setRadius(radius);\n circleElement.setFill(fillColor);\n circleElement.setOpacity(opacity);\n circleElement.setStrokeColor(strokeColor);\n circleElement.setLineWidth(lineWidth);\n updateElement?.(circleElement);\n } else {\n circleElement = new CircleElement(fillColor, radius)\n .setOpacity(opacity)\n .setStrokeColor(strokeColor)\n .setLineWidth(lineWidth);\n addElement?.(circleElement);\n }\n };\n\n useEffect(() => {\n if (selectedElement instanceof CircleElement) {\n setRadius(selectedElement.getRadius() ?? DEFAULT_CIRCLE_PROPS.radius);\n setFillColor(selectedElement.getFill() ?? DEFAULT_CIRCLE_PROPS.fillColor);\n setOpacity(selectedElement.getOpacity() ?? DEFAULT_CIRCLE_PROPS.opacity);\n setStrokeColor(selectedElement.getStrokeColor() ?? DEFAULT_CIRCLE_PROPS.strokeColor);\n setLineWidth(selectedElement.getLineWidth() ?? DEFAULT_CIRCLE_PROPS.lineWidth);\n }\n }, [selectedElement]);\n\n return {\n radius,\n fillColor,\n opacity,\n strokeColor,\n lineWidth,\n operation: selectedElement instanceof CircleElement ? \"Apply Changes\": \"Add Circle\",\n setRadius,\n setFillColor,\n setOpacity,\n setStrokeColor,\n setLineWidth,\n handleApplyChanges,\n };\n};\n","import type { PanelProps } from \"../../types\";\nimport { CirclePanel } from \"../panel/circle-panel\";\nimport { useCirclePanel } from \"../../hooks/use-circle-panel\";\n\nexport function CirclePanelContainer(props: PanelProps) {\n const circlePanelProps = useCirclePanel({\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n });\n return <CirclePanel {...circlePanelProps} />;\n}","/**\n * SubtitlesPanel Component\n *\n * A presentational panel for managing subtitle entries in the studio.\n * Renders a list of subtitle 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 (SubtitleEntry):\n * - `s`: start time (seconds)\n * - `e`: end time (seconds)\n * - `t`: subtitle text\n *\n * Props:\n * - `subtitles`: SubtitleEntry[] — ordered list of subtitles\n * - `addSubtitle()`: add a new subtitle at the end\n * - `splitSubtitle(index)`: split the subtitle at `index`\n * - `deleteSubtitle(index)`: remove the subtitle at `index`\n * - `updateSubtitle(index, subtitle)`: update the subtitle at `index`\n *\n * @component\n * @example\n * ```tsx\n * <SubtitlesPanel\n * subtitles={subtitles}\n * addSubtitle={addSubtitle}\n * splitSubtitle={splitSubtitle}\n * deleteSubtitle={deleteSubtitle}\n * updateSubtitle={updateSubtitle}\n * />\n * ```\n */\n\nimport { Trash2, Scissors } from \"lucide-react\";\n\ninterface SubtitleEntry {\n s: number;\n e: number;\n t: string; \n}\n\nexport function SubtitlesPanel({\n subtitles,\n addSubtitle,\n splitSubtitle,\n deleteSubtitle,\n updateSubtitle,\n}: {\n subtitles: SubtitleEntry[];\n addSubtitle: () => void;\n splitSubtitle: (index: number) => void;\n deleteSubtitle: (index: number) => void;\n updateSubtitle: (index: number, subtitle: SubtitleEntry) => void;\n}) {\n\n return (\n <div className=\"panel-container\">\n <h3 className=\"panel-title\">Subtitles</h3>\n\n {/* Subtitle Entries */}\n {subtitles.map((subtitle, i) => (\n <div\n key={i}\n className=\"panel-section gap-2\"\n >\n {/* Subtitle Text Input */}\n <div>\n <input\n type=\"text\"\n placeholder=\"Enter subtitle text\"\n value={subtitle.t}\n onChange={(e) => updateSubtitle(i, { ...subtitle, t: e.target.value })}\n className=\"input-dark\"\n />\n </div>\n\n {/* Action Buttons (bottom-right) */}\n <div className=\"flex-container justify-between\">\n <button\n onClick={() => splitSubtitle(i)}\n className=\"btn-ghost\"\n title=\"Split subtitle\"\n >\n <Scissors className=\"icon-sm\" />\n </button>\n <button\n onClick={() => deleteSubtitle(i)}\n className=\"btn-ghost\"\n title=\"Delete subtitle\"\n >\n <Trash2 className=\"icon-sm\" color=\"var(--color-red-500)\"/>\n </button>\n </div>\n </div>\n ))}\n\n {/* Common Add Button */}\n <div className=\"panel-section\">\n <button onClick={addSubtitle} className=\"btn-primary w-full\" title=\"Add subtitle\">\n Add\n </button>\n </div>\n </div>\n );\n}\n","import { CAPTION_STYLE } from \"@twick/timeline\";\n\nexport const CAPTION_PROPS = {\n [CAPTION_STYLE.WORD_BG_HIGHLIGHT]: {\n font: {\n size: 50,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n },\n lineWidth: 0.35,\n stroke: \"#000000\",\n fontWeight: 700,\n shadowOffset: [-3, 3],\n shadowColor: \"#000000\",\n },\n [CAPTION_STYLE.WORD_BY_WORD]: {\n font: {\n size: 50,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n }, \n lineWidth: 0.35,\n stroke: \"#000000\",\n shadowOffset: [-2, 2],\n shadowColor: \"#000000\",\n shadowBlur: 5,\n },\n [CAPTION_STYLE.WORD_BY_WORD_WITH_BG]: {\n font: {\n size: 50,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n },\n lineWidth: 0.35,\n shadowOffset: [-2, 2],\n shadowColor: \"#000000\",\n shadowBlur: 5,\n }\n };","import { useState, useEffect, useRef } from \"react\";\nimport { CAPTION_STYLE, CaptionElement, Track, useTimelineContext } from \"@twick/timeline\";\nimport { CAPTION_PROPS } from \"../helpers/constant\";\n\ninterface SubtitleEntry {\n s: number;\n e: number;\n t: string;\n}\n\nexport const useSubtitlesPanel = () => {\n const [subtitles, setSubtitles] = useState<SubtitleEntry[]>([]);\n const subtitlesTrack = useRef<Track | null>(null);\n const { editor } = useTimelineContext();\n\n const fetchSubtitles = async () => {\n const editorSubtitlesTrack = editor.getSubtiltesTrack();\n if (editorSubtitlesTrack) {\n subtitlesTrack.current = editorSubtitlesTrack;\n setSubtitles(\n editorSubtitlesTrack.getElements().map((element) => ({\n s: element.getStart(),\n e: element.getEnd(),\n t: (element as CaptionElement).getText(),\n }))\n );\n }\n };\n\n useEffect(() => {\n fetchSubtitles();\n }, []);\n\n const checkSubtitlesTrack = () => {\n if (!subtitlesTrack.current) {\n subtitlesTrack.current = editor.addTrack(\"Subtitles\", \"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 subtitlesTrack.current?.setProps(props);\n }\n };\n\n const addSubtitle = () => {\n const newSubtitle: SubtitleEntry = { s: 0, e: 0, t: \"New Subtitle\" };\n if (subtitles.length > 0) {\n newSubtitle.s = subtitles[subtitles.length - 1].e;\n }\n newSubtitle.e = newSubtitle.s + 1;\n setSubtitles([...subtitles, newSubtitle]);\n checkSubtitlesTrack();\n const captionElement = new CaptionElement(\n newSubtitle.t,\n newSubtitle.s,\n newSubtitle.e\n );\n editor.addElementToTrack(subtitlesTrack.current as Track, captionElement);\n };\n\n const splitSubtitle = async (index: number) => {\n if (subtitlesTrack.current) {\n const element = subtitlesTrack.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 fetchSubtitles();\n }\n }\n };\n\n const deleteSubtitle = (index: number) => {\n setSubtitles(subtitles.filter((_, i) => i !== index));\n if (subtitlesTrack.current) {\n editor.removeElement(subtitlesTrack.current.getElements()[index]);\n }\n };\n\n const updateSubtitle = (index: number, subtitle: SubtitleEntry) => {\n setSubtitles(subtitles.map((sub, i) => (i === index ? subtitle : sub)));\n if (subtitlesTrack.current) {\n const element = subtitlesTrack.current.getElements()[\n index\n ] as CaptionElement;\n element.setText(subtitle.t);\n editor.updateElement(element);\n }\n };\n\n return {\n subtitles,\n addSubtitle,\n splitSubtitle,\n deleteSubtitle,\n updateSubtitle,\n };\n};\n","import { SubtitlesPanel } from \"../panel/subtitles-panel\";\nimport { useSubtitlesPanel } from \"../../hooks/use-subtitles-panel\";\n\nexport function SubtitlesPanelContainer() {\n const subtitlesPanelProps = useSubtitlesPanel();\n return <SubtitlesPanel {...subtitlesPanelProps} />;\n}","import React from \"react\";\nimport { Size, TrackElement } from \"@twick/timeline\";\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 { IconPanelContainer } from \"./icon-panel-container\";\nimport { RectPanelContainer } from \"./rect-panel-container\";\nimport { CirclePanelContainer } from \"./circle-panel-container\";\nimport { Wand2 } from \"lucide-react\";\nimport { SubtitlesPanelContainer } from \"./subtitles-panel-container\";\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}\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 subtitles. 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}: 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 switch (selectedTool) {\n case \"image\":\n return (\n <ImagePanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"audio\":\n return (\n <AudioPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"video\":\n return (\n <VideoPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"text\":\n return (\n <TextPanelContainer\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"icon\":\n return (\n <IconPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"rect\":\n return (\n <RectPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"circle\":\n return (\n <CirclePanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"subtitle\":\n return <SubtitlesPanelContainer />;\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","/**\n * PropsToolbar Component\n *\n * A vertical toolbar that provides quick access to different property sections\n * for the selected element. Displays icons for each section.\n *\n * @component\n * @param {Object} props\n * @param {TrackElement} props.selectedElement - The currently selected element to display properties for\n * @param {string} props.selectedProp - The currently selected property to display\n * @param {Function} props.setSelectedProp - The function to set the currently selected property\n *\n * @example\n * ```tsx\n * <PropsToolbar\n * selectedElement={someElement}\n * selectedProp={someProp}\n * setSelectedProp={someFunction}\n * />\n * ```\n */\n\nimport {\n Type,\n Image,\n Music,\n Infinity,\n Zap,\n MessageSquare,\n Captions,\n Plus,\n Settings,\n SparklesIcon,\n} from \"lucide-react\";\nimport type { ToolCategory } from \"../types\";\nimport {\n AudioElement,\n CaptionElement,\n CircleElement,\n IconElement,\n ImageElement,\n RectElement,\n TextElement,\n TrackElement,\n VideoElement,\n} from \"@twick/timeline\";\nimport { useEffect, useMemo } from \"react\";\n\nconst propsCategories: Map<string, ToolCategory> = new Map([\n [\n \"element-props\",\n {\n id: \"element-props\",\n name: \"Properties\",\n icon: \"Settings\",\n description: \"Element Properties\",\n },\n ],\n [\n \"animations\",\n {\n id: \"animations\",\n name: \"Animations\",\n icon: \"Zap\",\n description: \"Animations\",\n },\n ],\n [\n \"text-effects\",\n {\n id: \"text-effects\",\n name: \"Text Effects\",\n icon: \"SparklesIcon\",\n description: \"Text Effects\",\n },\n ],\n [\n \"color-effects\",\n {\n id: \"color-effects\",\n name: \"Color Effects\",\n icon: \"Image\",\n description: \"Color Effects\",\n },\n ],\n [\n \"playback-props\",\n {\n id: \"playback-props\",\n name: \"Playback Props\",\n icon: \"Music\",\n description: \"Playback Properties\",\n },\n ],\n [\n \"subtitle-style\",\n {\n id: \"subtitle-style\",\n name: \"Subtitle Style\",\n icon: \"MessageSquare\",\n description: \"Subtitle Style\",\n },\n ],\n [\n \"generate-subtitles\",\n {\n id: \"generate-subtitles\",\n name: \"Generate Subtitles\",\n icon: \"Subtitles\",\n description: \"Generate Subtitles\",\n },\n ],\n]);\n\nconst getIcon = (iconName: string) => {\n switch (iconName) {\n case \"Type\":\n return Type;\n case \"Infinity\":\n return Infinity;\n case \"Image\":\n return Image;\n case \"Music\":\n return Music;\n case \"Subtitles\":\n return Captions;\n case \"MessageSquare\":\n return MessageSquare;\n case \"Settings\":\n return Settings;\n case \"SparklesIcon\":\n return SparklesIcon;\n case \"Zap\":\n return Zap;\n default:\n return Plus;\n }\n};\n\nexport function PropsToolbar({\n selectedElement,\n selectedProp,\n setSelectedProp,\n}: {\n selectedElement: TrackElement | null;\n selectedProp: string;\n setSelectedProp: (prop: string) => void;\n}) {\n const availableSections = useMemo(() => {\n const sections: ToolCategory[] = [];\n if (selectedElement instanceof TextElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n sections.push(propsCategories.get(\"text-effects\")!);\n } else if (selectedElement instanceof ImageElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n sections.push(propsCategories.get(\"color-effects\")!);\n } else if (selectedElement instanceof VideoElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n sections.push(propsCategories.get(\"color-effects\")!);\n sections.push(propsCategories.get(\"playback-props\")!);\n sections.push(propsCategories.get(\"generate-subtitles\")!);\n } else if (selectedElement instanceof AudioElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"playback-props\")!);\n } else if (selectedElement instanceof CircleElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n } else if (selectedElement instanceof RectElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n } else if (selectedElement instanceof IconElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n } else if (selectedElement instanceof CaptionElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n sections.push(propsCategories.get(\"subtitle-style\")!);\n }\n return sections;\n }, [selectedElement]);\n\n useEffect(() => {\n if (availableSections?.length) {\n if (\n availableSections.map((section) => section.id).indexOf(selectedProp) ===\n -1\n ) {\n setSelectedProp(availableSections[0].id);\n }\n }\n }, [availableSections]);\n \n return (\n <div className=\"sidebar\">\n {/* Main Tools */}\n {availableSections.map((tool) => {\n const Icon = getIcon(tool.icon);\n const isSelected = selectedProp === tool.id;\n return (\n <div\n key={tool.id}\n onClick={() => setSelectedProp(tool.id)}\n className={`toolbar-btn ${isSelected ? \"active\" : \"\"}`}\n title={`${tool.name}${tool.shortcut ? ` (${tool.shortcut})` : \"\"}`}\n >\n <Icon className=\"icon-sm\" />\n <span className=\"props-toolbar-label\">{tool.name}</span>\n </div>\n );\n })}\n </div>\n );\n}\n","import type { PropertiesPanelProps } from \"../../types\";\n\nexport function ElementProps({ selectedElement, updateElement }: PropertiesPanelProps) {\n const elementProps = selectedElement?.getProps() || {};\n const {x, y, opacity, rotation} = elementProps;\n\n const handleUpdateElement = (props: Record<string, any>) => {\n if(selectedElement) {\n updateElement?.(selectedElement?.setProps({...elementProps,...props}));\n }\n }\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">All Properties</div>\n <div className=\"panel-section\">\n <label className=\"label-dark\">Position</label>\n <div className=\"flex-container\">\n <div>\n <label className=\"label-small\">X</label>\n <input\n type=\"number\"\n value={x ?? 0}\n onChange={(e) => handleUpdateElement({ x: Number(e.target.value)})}\n className=\"input-dark\"\n />\n </div>\n <div>\n <label className=\"label-small\">Y</label>\n <input\n type=\"number\"\n value={y ?? 0}\n onChange={(e) => handleUpdateElement({ y: Number(e.target.value)})}\n className=\"input-dark\"\n />\n </div>\n </div>\n </div>\n\n {/* Opacity */}\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 value={(opacity ?? 1) * 100}\n onChange={(e) => handleUpdateElement({ opacity: Number(e.target.value) / 100})}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{Math.round((opacity ?? 1) * 100)}%</span>\n </div>\n </div>\n\n {/* Rotation */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Rotation</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"360\"\n value={rotation ?? 0}\n onChange={(e) => handleUpdateElement({ rotation: Number(e.target.value)})}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{rotation ?? 0}°</span>\n </div>\n </div>\n </div>\n );\n}\n","import { TEXT_EFFECTS } from \"@twick/video-editor\";\nimport { ElementTextEffect, TextElement } from \"@twick/timeline\";\nimport type { PropertiesPanelProps } from \"../../types\";\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 return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Text Effects</div>\n {/* Text Effect Selection */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Text Effect Type</label>\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 </div>\n\n {/* Text Effect Options */}\n {currentEffect && (\n <>\n {/* Delay */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Delay (seconds)</label>\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 </div>\n\n {/* Duration */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Duration (seconds)</label>\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 </div>\n\n {/* Buffer Time */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Buffer Time (seconds)</label>\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({ bufferTime: Number(e.target.value) })\n }\n className=\"input-dark\"\n />\n </div>\n </>\n )}\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 type { PropertiesPanelProps } from \"../../types\";\nexport function PlaybackPropsPanel({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n const elementProps = selectedElement?.getProps() || {};\n const { volume } = elementProps;\n\n const handleUpdateElement = (props: Record<string, any>) => {\n if (selectedElement) {\n updateElement?.(selectedElement?.setProps({ ...elementProps, ...props }));\n }\n };\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Playback Properties</div>\n {/* Volume */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Volume</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"3\"\n step={0.1}\n value={volume ?? 0}\n onChange={(e) =>\n handleUpdateElement({ volume: Number(e.target.value) })\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{volume ?? 0}</span>\n </div>\n </div>\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 video = document.createElement(\"video\");\n video.preload = \"metadata\";\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 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 = () => reject(new Error(\"Failed to load video metadata\"));\n });\n};\n\nconst getThumbnail = async (videoUrl, seekTime = 0.1, playbackRate = 1) => {\n return new Promise((resolve, reject) => {\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 = 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 reject(new Error(`Failed to load video: ${video.error?.message || \"Unknown error\"}`));\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;\n }).catch(() => {\n video.currentTime = seekTime;\n });\n } else {\n video.currentTime = seekTime;\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};\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) {\n console.warn(`Invalid segment: start (${segment.s}) >= end (${segment.e})`);\n continue;\n }\n const volume = segment.volume ?? 1;\n if (volume <= 0) {\n console.warn(`Skipping muted segment: ${segment.src}`);\n continue;\n }\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 (error) {\n console.warn(`Failed to process segment: ${segment.src}`, error);\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-.js').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 console.error(\"Error downloading file:\", 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 (error) {\n console.error(\"Fetch failed:\", error);\n return null;\n }\n};\n\nexport { blobUrlToFile, detectMediaTypeFromUrl, downloadFile, extractAudio, getAudioDuration, getImageDimensions, getObjectFitSize, getScaledDimensions, getThumbnail, 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 { ISubtitleGenerationPollingResponse } from \"../../types\";\n\nexport function GenerateSubtitlesPanel({\n selectedElement,\n addSubtitlesToTimeline,\n onGenerateSubtitles,\n getSubtitleStatus,\n}: {\n selectedElement: TrackElement;\n addSubtitlesToTimeline: (subtitles: { s: number; e: number; t: string }[]) => void;\n onGenerateSubtitles: (videoElement: VideoElement) => Promise<string | null>;\n getSubtitleStatus: (reqId: string) => Promise<ISubtitleGenerationPollingResponse>;\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 (!getSubtitleStatus) {\n return;\n }\n setPollingStatus(\"polling\");\n setIsGenerating(true);\n setErrorMessage(null);\n\n const poll = async () => {\n try {\n const response = await getSubtitleStatus(reqId);\n\n \n if (response.status === \"completed\") {\n stopPolling();\n setPollingStatus(\"success\");\n setIsGenerating(false);\n \n // Add subtitles to timeline\n addSubtitlesToTimeline(response.subtitles || []);\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 subtitles\");\n console.error(\"Error generating subtitles:\", response.error);\n }\n } catch (error) {\n stopPolling();\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(error instanceof Error ? error.message : \"Failed to get subtitle status\");\n console.error(\"Error polling for subtitles:\", error);\n }\n };\n\n // Poll immediately, then every 2 seconds\n await poll();\n pollingIntervalRef.current = setInterval(poll, 2000);\n };\n\n const handleGenerateSubtitles = async () => {\n if (!(selectedElement instanceof VideoElement)) {\n return;\n }\n\n const videoElement = selectedElement as VideoElement;\n \n\n try {\n const reqId = await onGenerateSubtitles(videoElement);\n if (!reqId) {\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(\"Failed to start subtitle generation\");\n console.error(\"Error generating subtitles: Failed to start subtitle 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 subtitle generation\");\n console.error(\"Error generating subtitles:\", 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 Subtitles 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 subtitles</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 subtitles... 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\">Subtitles 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 subtitles\"}</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Generate Button */}\n {!isLoading && (\n <div className=\"flex panel-section\">\n <button\n onClick={handleGenerateSubtitles}\n disabled={!containsAudio || isGenerating}\n className=\"btn-primary w-full\"\n >\n {isGenerating ? \"Generating...\" : \"Generate Subtitles\"}\n </button>\n </div>\n )}\n </div>\n );\n}\n","import { ElementProps } from \"../properties/element-props\";\nimport { TextEffects } from \"../properties/text-effects\";\nimport { Animation } from \"../properties/animation\";\nimport { VideoElement, type TrackElement } from \"@twick/timeline\";\nimport { PlaybackPropsPanel } from \"../properties/playback-props\";\nimport { GenerateSubtitlesPanel } from \"../properties/generate-subtitles\";\nimport { ISubtitleGenerationPollingResponse, SubtitleEntry } from \"../../types\";\n\ninterface PropertiesPanelContainerProps {\n selectedProp: string;\n selectedElement: TrackElement | null;\n updateElement: (element: TrackElement) => void;\n addSubtitlesToTimeline: (subtitles: SubtitleEntry[]) => void;\n onGenerateSubtitles: (videoElement: VideoElement) => Promise<string | null>;\n getSubtitleStatus: (reqId: string) => Promise<ISubtitleGenerationPollingResponse>;\n}\n\nexport function PropertiesPanelContainer({\n selectedProp,\n selectedElement,\n updateElement,\n addSubtitlesToTimeline,\n onGenerateSubtitles,\n getSubtitleStatus,\n}: PropertiesPanelContainerProps) {\n if (!selectedElement) {\n return (\n <div className=\"panel-container\">\n <div className=\"properties-header\">\n <h3 className=\"properties-title\">Select Element to see properties</h3>\n </div>\n </div>\n );\n }\n\n if (selectedElement.getType() === \"caption\") {\n return (\n <div className=\"panel-container\">\n <div className=\"properties-header\">\n <h3 className=\"properties-title\">Not available for sub-title</h3>\n </div>\n </div>\n );\n }\n \n return (\n <>\n {/* Element Properties */}\n {selectedProp === \"element-props\" && (\n <ElementProps\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Playback Properties */}\n {selectedProp === \"playback-props\" && (\n <PlaybackPropsPanel\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Text Effects */}\n {selectedProp === \"text-effects\" && (\n <TextEffects\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Animations */}\n {selectedProp === \"animations\" && (\n <Animation\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n {\n selectedProp === \"generate-subtitles\" && (\n <GenerateSubtitlesPanel\n selectedElement={selectedElement}\n addSubtitlesToTimeline={addSubtitlesToTimeline}\n onGenerateSubtitles={onGenerateSubtitles}\n getSubtitleStatus={getSubtitleStatus}\n />\n )\n }\n </>\n );\n}\n","import { ProjectJSON, useTimelineContext, VideoElement } from \"@twick/timeline\";\nimport { ISubtitleGenerationPollingResponse, StudioConfig, SubtitleEntry } from \"../types\";\nimport { loadFile, saveAsFile } from \"@twick/media-utils\";\nimport { useState } from \"react\";\n\nconst useStudioOperation = (studioConfig?: StudioConfig) => {\n const { editor, present } = useTimelineContext();\n const [projectName, setProjectName] = useState(\"\");\n const onLoadProject = async () => {\n let project: ProjectJSON;\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 console.log(\"Editor\", editor);\n editor.loadProject(project);\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: studioConfig.videoProps?.width,\n height: studioConfig.videoProps?.height,\n },\n });\n } else {\n alert(\"Export video not supported in demo mode\");\n }\n };\n\n\n\n /**\n * Generates subtitles using the new polling-based service\n * Returns a function that can be called to start the generation process\n */\n const onGenerateSubtitles = async (videoElement: VideoElement) => {\n // Use new polling-based service if available\n if (studioConfig?.subtitleGenerationService) {\n const service = studioConfig.subtitleGenerationService;\n const reqId = await service.generateSubtitles(videoElement, present as ProjectJSON);\n return reqId;\n }\n alert(\"Generate subtitles not supported in demo mode\");\n return null;\n };\n\n const addSubtitlesToTimeline = (subtitles: SubtitleEntry[]) => {\n const updatedProjectJSON = studioConfig?.subtitleGenerationService?.updateProjectWithSubtitles(subtitles);\n if (updatedProjectJSON) {\n editor.loadProject(updatedProjectJSON);\n }\n }\n\n const getSubtitleStatus = async (reqId: string) => {\n if (studioConfig?.subtitleGenerationService) {\n const service = studioConfig.subtitleGenerationService;\n return await service.getRequestStatus(reqId);\n }\n return {\n status: \"failed\",\n error: \"Subtitle generation service not found\",\n } as ISubtitleGenerationPollingResponse;\n }\n\n return { \n onLoadProject, \n onSaveProject, \n onExportVideo, \n onGenerateSubtitles,\n addSubtitlesToTimeline,\n getSubtitleStatus,\n };\n};\n\nexport default useStudioOperation;\n","import { ProjectJSON, useTimelineContext, VideoElement } from \"@twick/timeline\";\nimport {\n ISubtitleGenerationPollingResponse,\n StudioConfig,\n SubtitleEntry,\n} from \"../types\";\n\nconst useGenerateSubtitles = (studioConfig?: StudioConfig) => {\n const { editor, present } = useTimelineContext();\n /**\n * Generates subtitles using the new polling-based service\n * Returns a function that can be called to start the generation process\n */\n const onGenerateSubtitles = async (videoElement: VideoElement) => {\n // Use new polling-based service if available\n if (studioConfig?.subtitleGenerationService) {\n const service = studioConfig.subtitleGenerationService;\n const reqId = await service.generateSubtitles(\n videoElement,\n present as ProjectJSON\n );\n return reqId;\n }\n alert(\"Generate subtitles not supported in demo mode\");\n return null;\n };\n\n const addSubtitlesToTimeline = (subtitles: SubtitleEntry[]) => {\n const updatedProjectJSON =\n studioConfig?.subtitleGenerationService?.updateProjectWithSubtitles(\n subtitles\n );\n if (updatedProjectJSON) {\n editor.loadProject(updatedProjectJSON);\n }\n };\n\n const getSubtitleStatus = async (reqId: string) => {\n if (studioConfig?.subtitleGenerationService) {\n const service = studioConfig.subtitleGenerationService;\n return await service.getRequestStatus(reqId);\n }\n return {\n status: \"failed\",\n error: \"Subtitle generation service not found\",\n } as ISubtitleGenerationPollingResponse;\n };\n\n return {\n onGenerateSubtitles,\n addSubtitlesToTimeline,\n getSubtitleStatus,\n };\n};\n\nexport default useGenerateSubtitles;\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 { PropsToolbar } from \"./props-toolbar\";\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 useGenerateSubtitles from \"../hooks/use-generate-subtitles\";\n\nexport function TwickStudio({ studioConfig }: { studioConfig?: StudioConfig }) {\n const {\n selectedTool,\n setSelectedTool,\n selectedProp,\n setSelectedProp,\n selectedElement,\n addElement,\n updateElement,\n } = useStudioManager();\n const { videoResolution, setVideoResolution } = useTimelineContext();\n const {\n onLoadProject,\n onSaveProject,\n onExportVideo,\n } = useStudioOperation(studioConfig);\n\n const { onGenerateSubtitles, addSubtitlesToTimeline, getSubtitleStatus } =\n useGenerateSubtitles(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 },\n }),\n [videoResolution, studioConfig]\n );\n\n return (\n <MediaProvider>\n <div className=\"studio-container\">\n {/* Header */}\n <StudioHeader\n setVideoResolution={setVideoResolution}\n onLoadProject={onLoadProject}\n onSaveProject={onSaveProject}\n onExportVideo={onExportVideo}\n />\n {/* Main Content */}\n <div className=\"studio-content\">\n {/* Left Toolbar */}\n <Toolbar\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n />\n\n {/* Left Panel */}\n <ElementPanelContainer\n videoResolution={videoResolution}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n selectedElement={selectedElement}\n addElement={addElement}\n updateElement={updateElement}\n />\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 ?? 960,\n }}\n >\n <VideoEditor editorConfig={twickStudiConfig} />\n </div>\n </div>\n </main>\n\n {/* Left Panel */}\n <PropertiesPanelContainer\n selectedProp={selectedProp}\n selectedElement={selectedElement}\n updateElement={updateElement}\n addSubtitlesToTimeline={addSubtitlesToTimeline}\n onGenerateSubtitles={onGenerateSubtitles}\n getSubtitleStatus={getSubtitleStatus}\n />\n\n {/* Right Toolbar */}\n <PropsToolbar\n selectedElement={selectedElement}\n selectedProp={selectedProp}\n setSelectedProp={setSelectedProp}\n />\n </div>\n </div>\n </MediaProvider>\n );\n}\n"],"names":["forwardRef","createElement","__iconNode","getIcon","Icon","jsxs","jsx","useState","useEffect","orientation","useTimelineContext","useEditorManager","TrackElement","useRef","Track","BrowserMediaManager","createContext","useContext","VideoElement","AudioElement","ImageElement","config","useCallback","Wand2","AVAILABLE_TEXT_FONTS","TextElement","Loader2","IconElement","RectElement","CircleElement","CAPTION_STYLE","CaptionElement","SparklesIcon","useMemo","ElementTextEffect","TEXT_EFFECTS","Fragment","ANIMATIONS","ElementAnimation","CheckCircle2","XCircle"],"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]}
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/captions.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/infinity.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.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/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/settings.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","../../../node_modules/.pnpm/lucide-react@0.511.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/zap.js","../src/components/toolbar.tsx","../src/components/header.tsx","../src/hooks/use-studio-manager.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/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/shared/search-input.tsx","../src/components/panel/icon-panel.tsx","../src/hooks/use-icon-panel.ts","../src/components/container/icon-panel-container.tsx","../src/components/panel/rect-panel.tsx","../src/hooks/use-rect-panel.ts","../src/components/container/rect-panel-container.tsx","../src/components/panel/circle-panel.tsx","../src/hooks/use-circle-panel.ts","../src/components/container/circle-panel-container.tsx","../src/components/panel/subtitles-panel.tsx","../src/helpers/constant.ts","../src/hooks/use-subtitles-panel.ts","../src/components/container/subtitles-panel-container.tsx","../src/components/container/element-panel-container.tsx","../src/components/props-toolbar.tsx","../src/components/properties/element-props.tsx","../src/components/properties/text-effects.tsx","../src/components/properties/animation.tsx","../src/components/properties/playback-props.tsx","../../media-utils/dist/index.mjs","../src/components/properties/generate-subtitles.tsx","../src/components/container/properties-panel-container.tsx","../src/hooks/use-studio-operation.ts","../src/hooks/use-generate-subtitles.ts","../src/components/twick-studio.tsx"],"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 [\"rect\", { width: \"18\", height: \"14\", x: \"3\", y: \"5\", rx: \"2\", ry: \"2\", key: \"12ruh7\" }],\n [\"path\", { d: \"M7 15h4M15 15h2M7 11h2M13 11h4\", key: \"1ueiar\" }]\n];\nconst Captions = createLucideIcon(\"captions\", __iconNode);\n\nexport { __iconNode, Captions as default };\n//# sourceMappingURL=captions.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 [\"path\", { d: \"M6 16c5 0 7-8 12-8a4 4 0 0 1 0 8c-5 0-7-8-12-8a4 4 0 1 0 0 8\", key: \"18ogeb\" }]\n];\nconst Infinity = createLucideIcon(\"infinity\", __iconNode);\n\nexport { __iconNode, Infinity as default };\n//# sourceMappingURL=infinity.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 [\"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 [\"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 [\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: \"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\",\n key: \"1qme2f\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n];\nconst Settings = createLucideIcon(\"settings\", __iconNode);\n\nexport { __iconNode, Settings as default };\n//# sourceMappingURL=settings.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 * @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: \"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z\",\n key: \"1xq2db\"\n }\n ]\n];\nconst Zap = createLucideIcon(\"zap\", __iconNode);\n\nexport { __iconNode, Zap as default };\n//# sourceMappingURL=zap.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 Infinity, \n MessageSquare,\n Plus,\n Square,\n} from 'lucide-react'\nimport type { ToolCategory } from '../types'\n\nconst toolCategories: ToolCategory[] = [\n { id: 'video', name: 'Video', icon: 'Video', description: 'Video' },\n { id: 'image', name: 'Image', icon: 'Image', description: 'Image' },\n { id: 'audio', name: 'Audio', icon: 'Audio', description: 'Audio' },\n { id: 'text', name: 'Text', icon: 'Type', description: 'Add text elements', shortcut: 'T' },\n { id: 'icon', name: 'Icons', icon: 'Icon', description: 'Icon Element', shortcut: 'I' },\n { id: 'circle', name: 'Circle', icon: 'Circle', description: 'Circle Element', shortcut: 'C' },\n { id: 'rect', name: 'Rect', icon: 'Rect', description: 'Rect Element' },\n { id: 'subtitle', name: 'Subtitles', icon: 'MessageSquare', description: 'Manage subtitles', shortcut: 'S' },\n]\n\nconst getIcon = (iconName: string) => {\n switch (iconName) {\n case 'Plus': return Plus\n case 'Type': return Type\n case 'Icon': return Infinity\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 default: return Plus\n }\n}\n\nexport function Toolbar({ selectedTool, setSelectedTool }: { selectedTool: string, setSelectedTool: (tool: string) => void }) {\n\n const handleToolSelect = (toolId: string) => {\n setSelectedTool(toolId)\n }\n\n return (\n <div className=\"sidebar\">\n {/* Main Tools */}\n {toolCategories.map((tool) => {\n const Icon = getIcon(tool.icon)\n const isSelected = selectedTool === tool.id\n \n return (\n <div\n key={tool.id}\n onClick={() => handleToolSelect(tool.id)}\n className={`toolbar-btn ${isSelected ? 'active' : ''}`}\n title={`${tool.name}${tool.shortcut ? ` (${tool.shortcut})` : ''}`}\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 } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\n\ninterface StudioHeaderProps {\n setVideoResolution: (resolution: Size) => void;\n onLoadProject: () => void;\n onSaveProject: () => void;\n onExportVideo: () => void;\n}\nexport const StudioHeader = ({\n setVideoResolution,\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 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 <div className=\"flex-container\">\n <Clapperboard className=\"icon-lg accent-purple\" />\n <h1 className=\"text-gradient\">\n Twick Studio\n </h1>\n </div>\n </div>\n <div className=\"flex-container\">\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-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\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\n // const addSubtitlesToTimeline = (elements: TrackElement[]) => {\n // if (selectedItem instanceof Track && selectedItem.getType() == \"caption\") {\n // elements.forEach((element) => {\n // editor.addElementToTrack(selectedItem, element);\n // });\n // } else {\n // const newTrack = editor.addTrack(\"Track\", \"caption\");\n // elements.forEach((element) => {\n // editor.addElementToTrack(newTrack, element);\n // });\n // }\n // };\n\n useEffect(() => {\n if (selectedItem instanceof TrackElement) {\n setSelectedTool(selectedItem.getType());\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 { 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 // Reset the promise on error so initialization can be retried\n MediaManagerSingleton.initializationPromise = null;\n console.error(\"Error initializing default media:\", error);\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 console.log(`Added ${finalVideosToAdd.length} default video(s) to media library`);\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 console.log(`Added ${finalImagesToAdd.length} default image(s) to media library`);\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 console.log(`Added ${finalAudiosToAdd.length} default audio file(s) to media library`);\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 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}: 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 {/* Upload */}\n {/* <div className=\"flex panel-section\">\n <FileInput\n id=\"audio-upload\"\n acceptFileTypes={acceptFileTypes}\n onFileLoad={onFileUpload}\n buttonText=\"Import media\"\n className=\"btn-primary w-full\"\n icon={<Upload className=\"icon-sm\" />}\n />\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 onDoubleClick={() => onItemSelect(item)}\n className=\"media-list-item\"\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 </div>\n </div>\n );\n};","import { 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 } from \"../shared\";\n\nexport const AudioPanelContainer = (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(\"audio\", {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution);\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 return (\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 * 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 type { ImagePanelProps } from \"../../types/media-panel\";\nimport UrlInput from \"../shared/url-input\";\n\nexport function ImagePanel({\n items,\n onItemSelect,\n onUrlAdd,\n}: ImagePanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Image Library</div>\n\n {/* Add by URL */}\n <div className=\"panel-section\">\n <UrlInput type=\"image\" onSubmit={onUrlAdd} />\n </div>\n {/* Upload */}\n {/* <div className=\"flex panel-section\">\n <FileInput\n id=\"image-upload\"\n acceptFileTypes={acceptFileTypes}\n onFileLoad={onFileUpload}\n buttonText=\"Import media\"\n className=\"btn-primary w-full\"\n icon={<Upload className=\"icon-sm\" />}\n />\n </div> */}\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 onDoubleClick={() => onItemSelect(item)}\n className=\"media-item\"\n >\n <img src={item.url} alt=\"\" className=\"media-item-content\" />\n\n {/* Quick Actions */}\n <div className=\"media-actions\">\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 </div>\n </div>\n );\n}\n","import 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 } from \"../shared\";\n\nexport function ImagePanelContainer(props: PanelProps) {\n const { addItem } = useMedia(\"image\");\n const mediaManager = getMediaManager();\n const {\n items,\n searchQuery,\n setSearchQuery,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes,\n } = useMediaPanel(\"image\", {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution);\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 return (\n <ImagePanel\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","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 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}: 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 <div className=\"flex panel-section\">\n <UrlInput type=\"video\" onSubmit={onUrlAdd} />\n </div>\n\n {/* Import Button */}\n {/* <div className=\"flex panel-section\">\n <FileInput\n id=\"video-upload\"\n acceptFileTypes={acceptFileTypes}\n onFileLoad={onFileUpload}\n buttonText=\"Import media\"\n className=\"btn-primary w-full\"\n icon={<Upload className=\"icon-sm\" />}\n />\n </div> */}\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 onDoubleClick={() => onItemSelect(item)}\n className=\"media-item\"\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 {/* Quick Actions */}\n <div className=\"media-actions\">\n {/* Play/Pause button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n const videoEl = 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\n {/* 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 videos found</p>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n}","import 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 } from \"../shared\";\n\nexport function VideoPanelContainer(props: PanelProps) {\n const { addItem } = useMedia(\"video\");\n const mediaManager = getMediaManager();\n const {\n items,\n handleSelection,\n handleFileUpload,\n isLoading,\n acceptFileTypes,\n } = useMediaPanel(\"video\", {\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n },\n props.videoResolution);\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 return (\n <VideoPanel\n items={items}\n onItemSelect={handleSelection}\n onFileUpload={handleFileUpload}\n isLoading={isLoading}\n acceptFileTypes={acceptFileTypes}\n onUrlAdd={onUrlAdd}\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 {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 {() => 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 fonts,\n operation,\n setTextContent,\n setFontSize,\n setSelectedFont,\n setIsBold,\n setIsItalic,\n setTextColor,\n setStrokeColor,\n setApplyShadow,\n setShadowColor,\n setStrokeWidth,\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 {/* Operation button */}\n <div className=\"flex panel-section\">\n <button onClick={handleApplyChanges} className=\"btn-primary w-full\">\n {operation}\n </button>\n </div>\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 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 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\n const fonts = Object.values(AVAILABLE_TEXT_FONTS);\n\n const handleApplyChanges = async () => {\n let textElement;\n if (selectedElement instanceof TextElement) {\n textElement = selectedElement;\n textElement.setText(textContent);\n textElement.setFontSize(fontSize);\n textElement.setFontFamily(selectedFont);\n textElement.setFontWeight(isBold ? 700 : 400);\n textElement.setFontStyle(isItalic ? \"italic\" : \"normal\");\n textElement.setFill(textColor);\n textElement.setStrokeColor(strokeColor);\n textElement.setLineWidth(strokeWidth);\n textElement.setTextAlign(DEFAULT_TEXT_PROPS.textAlign);\n if (applyShadow) {\n textElement.setProps({\n ...textElement.getProps(),\n shadowColor,\n shadowOffset: DEFAULT_TEXT_PROPS.shadowOffset,\n shadowBlur: DEFAULT_TEXT_PROPS.shadowBlur,\n shadowOpacity: DEFAULT_TEXT_PROPS.shadowOpacity,\n });\n } else {\n textElement.setProps({\n ...textElement.getProps(),\n shadowColor: undefined,\n shadowOffset: undefined,\n shadowBlur: undefined,\n shadowOpacity: undefined,\n });\n }\n updateElement(textElement);\n } else {\n 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 if (applyShadow) {\n textElement.setProps({\n ...textElement.getProps(),\n shadowColor,\n shadowOffset: DEFAULT_TEXT_PROPS.shadowOffset,\n shadowBlur: DEFAULT_TEXT_PROPS.shadowBlur,\n shadowOpacity: DEFAULT_TEXT_PROPS.shadowOpacity,\n });\n }\n await addElement(textElement);\n }\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 } 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 }\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,\n setFontSize,\n setSelectedFont,\n setIsBold,\n setIsItalic,\n setTextColor,\n setStrokeColor,\n setApplyShadow,\n setShadowColor,\n setStrokeWidth,\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 { 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","/**\n * IconPanel Component\n *\n * A panel for browsing, searching, and adding icons to the studio timeline.\n * Features a searchable grid of SVG icons with preview, add, and download actions.\n * Supports infinite scrolling with \"Load More\" functionality.\n *\n * @component\n * @param {Object} props\n * @param {Icon[]} props.icons - List of icons to display\n * @param {boolean} props.loading - Loading state indicator\n * @param {boolean} props.hasMore - Whether more icons can be loaded\n * @param {number} props.totalIcons - Total number of available icons\n * @param {string} props.searchQuery - Current search query\n * @param {(query: string) => void} props.handleSearch - Handle search query changes\n * @param {(icon: Icon) => void} props.handleSelection - Handle icon selection\n * @param {(icon: Icon) => void} props.handleDownloadIcon - Handle icon download\n * @param {() => void} props.handleLoadMore - Load more icons\n *\n * @example\n * ```tsx\n * <IconPanel\n * icons={icons}\n * loading={false}\n * hasMore={true}\n * totalIcons={1000}\n * searchQuery=\"\"\n * handleSearch={setSearchQuery}\n * handleSelection={addIconToTimeline}\n * handleDownloadIcon={downloadSvg}\n * handleLoadMore={loadNextPage}\n * />\n * ```\n */\n\nimport { Loader2, Download, Plus } from \"lucide-react\";\nimport type {\n IconPanelState,\n IconPanelActions,\n Icon,\n} from \"../../hooks/use-icon-panel\";\nimport SearchInput from \"../shared/search-input\";\n\nexport type IconPanelProps = IconPanelState & IconPanelActions;\n\nexport function IconPanel({\n icons,\n loading,\n totalIcons,\n searchQuery,\n handleSearch,\n handleSelection,\n handleDownloadIcon,\n handleLoadMore,\n}: IconPanelProps) {\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Icon Library</div>\n\n {/* Search */}\n <div className=\"flex panel-section\">\n <SearchInput searchQuery={searchQuery} setSearchQuery={handleSearch} />\n </div>\n\n {/* Icons Grid */}\n <div className=\"media-content\">\n {/* Results Count */}\n {totalIcons > 0 && (\n <div className=\"media-count\">\n Showing {icons.length} of {totalIcons} icons\n </div>\n )}\n\n {/* Loading State */}\n {loading && icons.length === 0 ? (\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\">Loading icons...</p>\n </div>\n </div>\n ) : (\n <div className=\"icon-grid\">\n {(icons || []).map((icon: Icon, index: number) => (\n <div key={index} className=\"icon-item\">\n <div\n onClick={() => handleSelection(icon)}\n className=\"icon-content\"\n dangerouslySetInnerHTML={{ __html: icon.svg }}\n />\n\n {/* Quick Actions */}\n <div className=\"icon-actions\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n handleSelection(icon);\n }}\n className=\"icon-action-btn\"\n title=\"Add to timeline\"\n >\n <Plus className=\"icon-sm\" />\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n handleDownloadIcon(icon);\n }}\n className=\"icon-action-btn\"\n title=\"Download SVG\"\n >\n <Download className=\"icon-sm\" />\n </button>\n </div>\n\n {/* Icon name */}\n <div className=\"icon-name\">{icon.name}</div>\n </div>\n ))}\n </div>\n )}\n\n {/* Empty State */}\n {!loading && icons.length === 0 && searchQuery && (\n <div className=\"empty-state\">\n <div className=\"empty-state-content\">\n <p className=\"empty-state-text\">No icons found</p>\n <p className=\"empty-state-subtext\">Try a different search term</p>\n </div>\n </div>\n )}\n\n {!loading && totalIcons && icons.length < totalIcons && (\n <div className=\"flex panel-section\">\n <button\n onClick={handleLoadMore}\n disabled={loading}\n className=\"btn-primary\"\n >\n Load More Icons\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useState, useRef, useEffect } from \"react\";\nimport { IconElement, TrackElement } from \"@twick/timeline\";\n\nexport interface Icon {\n name: string;\n svg: string;\n}\n\nexport interface IconPanelState {\n icons: Icon[];\n loading: boolean;\n hasMore: boolean;\n totalIcons: number;\n searchQuery: string;\n}\n\nexport interface IconPanelActions {\n handleSearch: (query: string) => void;\n handleSelection: (icon: Icon) => void;\n handleDownloadIcon: (icon: Icon) => void;\n handleLoadMore: () => void;\n}\n\nconst ICONS_PER_PAGE = 20;\n\nexport const useIconPanel = ({\n selectedElement,\n addElement,\n updateElement,\n}: {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}): IconPanelState & IconPanelActions => {\n const [icons, setIcons] = useState<Icon[]>([]);\n const [loading, setLoading] = useState(false);\n const [page, setPage] = useState(1);\n const [hasMore, setHasMore] = useState(true);\n const [totalIcons, setTotalIcons] = useState(0);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const currentQuery = useRef(\"\");\n\n const fetchIcons = async (query: string, reset = false) => {\n try {\n setLoading(true);\n const newPage = reset ? 1 : page;\n const start = (newPage - 1) * ICONS_PER_PAGE;\n const url = `https://api.iconify.design/search?query=${query}&limit=${ICONS_PER_PAGE}&offset=${start}`;\n\n const response = await fetch(url);\n const data = await response.json();\n\n const iconData = data.icons || [];\n const total = data.total || 0;\n setTotalIcons(total);\n\n const formattedIcons = await Promise.all(\n iconData.map(async (icon: any) => {\n const svgUrl = `https://api.iconify.design/${icon}.svg`;\n\n try {\n const svgResponse = await fetch(svgUrl);\n const svg = await svgResponse.text();\n return { name: icon, svg };\n } catch (e) {\n console.error(`Error fetching SVG for ${icon}:`, e);\n return null;\n }\n })\n );\n\n const validIcons = formattedIcons.filter((icon) => icon !== null) as Icon[];\n\n if (reset) {\n setIcons(validIcons);\n } else {\n setIcons([...icons, ...validIcons]);\n }\n\n setHasMore(start + validIcons.length < total);\n if (!reset) {\n setPage(newPage + 1);\n } else {\n setPage(2);\n }\n } catch (error) {\n console.error(\"Error fetching icons:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n fetchIcons(\"media\", true);\n }, []);\n\n const handleSearch = (query: string) => {\n currentQuery.current = query;\n setSearchQuery(query);\n fetchIcons(query, true);\n };\n\n const handleSelection = (icon: Icon) => {\n const svgBlob = new Blob([icon.svg], { type: \"image/svg+xml\" });\n const url = URL.createObjectURL(svgBlob);\n\n let iconElement;\n if (selectedElement instanceof IconElement) {\n iconElement = selectedElement;\n iconElement.setSrc(url);\n iconElement.setName(icon.name);\n updateElement?.(iconElement);\n } else {\n iconElement = new IconElement(url, {\n width: 100,\n height: 100,\n });\n iconElement.setName(icon.name);\n addElement?.(iconElement);\n }\n\n URL.revokeObjectURL(url);\n };\n\n const handleDownloadIcon = (icon: Icon) => {\n const blob = new Blob([icon.svg], { type: \"image/svg+xml\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `${icon.name}.svg`;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n };\n\n const handleLoadMore = () => {\n fetchIcons(currentQuery.current, false);\n };\n\n return {\n icons,\n loading,\n hasMore,\n totalIcons,\n searchQuery,\n handleSearch,\n handleSelection,\n handleDownloadIcon,\n handleLoadMore,\n };\n};\n","import type { PanelProps } from \"../../types\";\nimport { IconPanel } from \"../panel/icon-panel\";\nimport { useIconPanel } from \"../../hooks/use-icon-panel\";\n\nexport function IconPanelContainer(props: PanelProps) {\n const iconPanelProps = useIconPanel({\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n });\n return <IconPanel {...iconPanelProps} />;\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 {number} props.opacity - Opacity percentage (0-100)\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 opacity,\n strokeColor,\n lineWidth,\n operation,\n setCornerRadius,\n setFillColor,\n setOpacity,\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 {/* Opacity */}\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 value={opacity}\n onChange={(e) => setOpacity(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{opacity}%</span>\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 */}\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 </div>\n );\n}","import { useEffect, useState } from \"react\";\nimport { RectElement, TrackElement } from \"@twick/timeline\";\n\nexport const DEFAULT_RECT_PROPS = {\n cornerRadius: 0,\n fillColor: \"#3b82f6\",\n opacity: 100,\n strokeColor: \"#000000\",\n lineWidth: 0,\n};\n\nexport interface RectPanelState {\n cornerRadius: number;\n fillColor: string;\n opacity: number;\n strokeColor: string;\n lineWidth: number;\n operation: string;\n}\n\nexport interface RectPanelActions {\n setCornerRadius: (radius: number) => void;\n setFillColor: (color: string) => void;\n setOpacity: (opacity: number) => void;\n setStrokeColor: (color: string) => void;\n setLineWidth: (width: number) => void;\n handleApplyChanges: () => void;\n}\n\nexport const useRectPanel = ({\n selectedElement,\n addElement,\n updateElement,\n}: {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}): RectPanelState & RectPanelActions => {\n const [cornerRadius, setCornerRadius] = useState(DEFAULT_RECT_PROPS.cornerRadius);\n const [fillColor, setFillColor] = useState(DEFAULT_RECT_PROPS.fillColor);\n const [opacity, setOpacity] = useState(DEFAULT_RECT_PROPS.opacity);\n const [strokeColor, setStrokeColor] = useState(DEFAULT_RECT_PROPS.strokeColor);\n const [lineWidth, setLineWidth] = useState(DEFAULT_RECT_PROPS.lineWidth);\n\n const handleApplyChanges = () => {\n let rectElement;\n if (selectedElement instanceof RectElement) {\n rectElement = selectedElement;\n rectElement.setCornerRadius(cornerRadius);\n rectElement.setOpacity(opacity);\n rectElement.setStrokeColor(strokeColor);\n rectElement.setLineWidth(lineWidth);\n updateElement?.(rectElement);\n } else {\n rectElement = new RectElement(fillColor, { width: 200, height: 200 })\n .setCornerRadius(cornerRadius)\n .setOpacity(opacity)\n .setStrokeColor(strokeColor)\n .setLineWidth(lineWidth);\n addElement?.(rectElement);\n }\n };\n\n useEffect(() => {\n if (selectedElement instanceof RectElement) {\n setCornerRadius(selectedElement.getCornerRadius() ?? DEFAULT_RECT_PROPS.cornerRadius);\n setFillColor(selectedElement.getFill() ?? DEFAULT_RECT_PROPS.fillColor);\n setOpacity(selectedElement.getOpacity() ?? DEFAULT_RECT_PROPS.opacity);\n setStrokeColor(selectedElement.getStrokeColor() ?? DEFAULT_RECT_PROPS.strokeColor);\n setLineWidth(selectedElement.getLineWidth() ?? DEFAULT_RECT_PROPS.lineWidth);\n }\n }, [selectedElement]);\n\n return {\n cornerRadius,\n fillColor,\n opacity,\n strokeColor,\n lineWidth,\n operation: selectedElement instanceof RectElement ? \"Apply Changes\": \"Add Rectangle\",\n setCornerRadius,\n setFillColor,\n setOpacity,\n setStrokeColor,\n setLineWidth,\n handleApplyChanges,\n };\n};\n","import type { PanelProps } from \"../../types\";\nimport { RectPanel } from \"../panel/rect-panel\";\nimport { useRectPanel } from \"../../hooks/use-rect-panel\";\n\nexport function RectPanelContainer(props: PanelProps) {\n const rectPanelProps = useRectPanel({\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n });\n return <RectPanel {...rectPanelProps} />;\n}\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 {number} props.opacity - Opacity percentage (0-100)\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 opacity,\n strokeColor,\n lineWidth,\n operation,\n setRadius,\n setFillColor,\n setOpacity,\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 {/* Opacity */}\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 value={opacity}\n onChange={(e) => setOpacity(Number(e.target.value))}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{opacity}%</span>\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 */}\n <div className=\"flex panel-section\">\n <button onClick={handleApplyChanges} className=\"btn-primary w-full\">\n {operation}\n </button>\n </div>\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { CircleElement, TrackElement } from \"@twick/timeline\";\n\nexport const DEFAULT_CIRCLE_PROPS = {\n radius: 50,\n fillColor: \"#3b82f6\",\n opacity: 100,\n strokeColor: \"#000000\",\n lineWidth: 0,\n};\n\nexport interface CirclePanelState {\n radius: number;\n fillColor: string;\n opacity: number;\n strokeColor: string;\n lineWidth: number;\n operation: string;\n}\n\nexport interface CirclePanelActions {\n setRadius: (radius: number) => void;\n setFillColor: (color: string) => void;\n setOpacity: (opacity: number) => void;\n setStrokeColor: (color: string) => void;\n setLineWidth: (width: number) => void;\n handleApplyChanges: () => void;\n}\n\nexport const useCirclePanel = ({\n selectedElement,\n addElement,\n updateElement,\n}: {\n selectedElement: TrackElement | null;\n addElement: (element: TrackElement) => void;\n updateElement: (element: TrackElement) => void;\n}): CirclePanelState & CirclePanelActions => {\n const [radius, setRadius] = useState(DEFAULT_CIRCLE_PROPS.radius);\n const [fillColor, setFillColor] = useState(DEFAULT_CIRCLE_PROPS.fillColor);\n const [opacity, setOpacity] = useState(DEFAULT_CIRCLE_PROPS.opacity);\n const [strokeColor, setStrokeColor] = useState(DEFAULT_CIRCLE_PROPS.strokeColor);\n const [lineWidth, setLineWidth] = useState(DEFAULT_CIRCLE_PROPS.lineWidth);\n\n const handleApplyChanges = () => {\n let circleElement;\n if (selectedElement instanceof CircleElement) {\n circleElement = selectedElement;\n circleElement.setRadius(radius);\n circleElement.setFill(fillColor);\n circleElement.setOpacity(opacity);\n circleElement.setStrokeColor(strokeColor);\n circleElement.setLineWidth(lineWidth);\n updateElement?.(circleElement);\n } else {\n circleElement = new CircleElement(fillColor, radius)\n .setOpacity(opacity)\n .setStrokeColor(strokeColor)\n .setLineWidth(lineWidth);\n addElement?.(circleElement);\n }\n };\n\n useEffect(() => {\n if (selectedElement instanceof CircleElement) {\n setRadius(selectedElement.getRadius() ?? DEFAULT_CIRCLE_PROPS.radius);\n setFillColor(selectedElement.getFill() ?? DEFAULT_CIRCLE_PROPS.fillColor);\n setOpacity(selectedElement.getOpacity() ?? DEFAULT_CIRCLE_PROPS.opacity);\n setStrokeColor(selectedElement.getStrokeColor() ?? DEFAULT_CIRCLE_PROPS.strokeColor);\n setLineWidth(selectedElement.getLineWidth() ?? DEFAULT_CIRCLE_PROPS.lineWidth);\n }\n }, [selectedElement]);\n\n return {\n radius,\n fillColor,\n opacity,\n strokeColor,\n lineWidth,\n operation: selectedElement instanceof CircleElement ? \"Apply Changes\": \"Add Circle\",\n setRadius,\n setFillColor,\n setOpacity,\n setStrokeColor,\n setLineWidth,\n handleApplyChanges,\n };\n};\n","import type { PanelProps } from \"../../types\";\nimport { CirclePanel } from \"../panel/circle-panel\";\nimport { useCirclePanel } from \"../../hooks/use-circle-panel\";\n\nexport function CirclePanelContainer(props: PanelProps) {\n const circlePanelProps = useCirclePanel({\n selectedElement: props.selectedElement ?? null,\n addElement: props.addElement!,\n updateElement: props.updateElement!,\n });\n return <CirclePanel {...circlePanelProps} />;\n}","/**\n * SubtitlesPanel Component\n *\n * A presentational panel for managing subtitle entries in the studio.\n * Renders a list of subtitle 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 (SubtitleEntry):\n * - `s`: start time (seconds)\n * - `e`: end time (seconds)\n * - `t`: subtitle text\n *\n * Props:\n * - `subtitles`: SubtitleEntry[] — ordered list of subtitles\n * - `addSubtitle()`: add a new subtitle at the end\n * - `splitSubtitle(index)`: split the subtitle at `index`\n * - `deleteSubtitle(index)`: remove the subtitle at `index`\n * - `updateSubtitle(index, subtitle)`: update the subtitle at `index`\n *\n * @component\n * @example\n * ```tsx\n * <SubtitlesPanel\n * subtitles={subtitles}\n * addSubtitle={addSubtitle}\n * splitSubtitle={splitSubtitle}\n * deleteSubtitle={deleteSubtitle}\n * updateSubtitle={updateSubtitle}\n * />\n * ```\n */\n\nimport { Trash2, Scissors } from \"lucide-react\";\n\ninterface SubtitleEntry {\n s: number;\n e: number;\n t: string; \n}\n\nexport function SubtitlesPanel({\n subtitles,\n addSubtitle,\n splitSubtitle,\n deleteSubtitle,\n updateSubtitle,\n}: {\n subtitles: SubtitleEntry[];\n addSubtitle: () => void;\n splitSubtitle: (index: number) => void;\n deleteSubtitle: (index: number) => void;\n updateSubtitle: (index: number, subtitle: SubtitleEntry) => void;\n}) {\n\n return (\n <div className=\"panel-container\">\n <h3 className=\"panel-title\">Subtitles</h3>\n\n {/* Subtitle Entries */}\n {subtitles.map((subtitle, i) => (\n <div\n key={i}\n className=\"panel-section gap-2\"\n >\n {/* Subtitle Text Input */}\n <div>\n <input\n type=\"text\"\n placeholder=\"Enter subtitle text\"\n value={subtitle.t}\n onChange={(e) => updateSubtitle(i, { ...subtitle, t: e.target.value })}\n className=\"input-dark\"\n />\n </div>\n\n {/* Action Buttons (bottom-right) */}\n <div className=\"flex-container justify-between\">\n <button\n onClick={() => splitSubtitle(i)}\n className=\"btn-ghost\"\n title=\"Split subtitle\"\n >\n <Scissors className=\"icon-sm\" />\n </button>\n <button\n onClick={() => deleteSubtitle(i)}\n className=\"btn-ghost\"\n title=\"Delete subtitle\"\n >\n <Trash2 className=\"icon-sm\" color=\"var(--color-red-500)\"/>\n </button>\n </div>\n </div>\n ))}\n\n {/* Common Add Button */}\n <div className=\"panel-section\">\n <button onClick={addSubtitle} className=\"btn-primary w-full\" title=\"Add subtitle\">\n Add\n </button>\n </div>\n </div>\n );\n}\n","import { CAPTION_STYLE } from \"@twick/timeline\";\n\nexport const CAPTION_PROPS = {\n [CAPTION_STYLE.WORD_BG_HIGHLIGHT]: {\n font: {\n size: 50,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n },\n lineWidth: 0.35,\n stroke: \"#000000\",\n fontWeight: 700,\n shadowOffset: [-3, 3],\n shadowColor: \"#000000\",\n },\n [CAPTION_STYLE.WORD_BY_WORD]: {\n font: {\n size: 50,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n }, \n lineWidth: 0.35,\n stroke: \"#000000\",\n shadowOffset: [-2, 2],\n shadowColor: \"#000000\",\n shadowBlur: 5,\n },\n [CAPTION_STYLE.WORD_BY_WORD_WITH_BG]: {\n font: {\n size: 50,\n weight: 700,\n family: \"Bangers\",\n },\n colors: {\n text: \"#ffffff\",\n highlight: \"#ff4081\",\n bgColor: \"#444444\",\n },\n lineWidth: 0.35,\n shadowOffset: [-2, 2],\n shadowColor: \"#000000\",\n shadowBlur: 5,\n }\n };","import { useState, useEffect, useRef } from \"react\";\nimport { CAPTION_STYLE, CaptionElement, Track, useTimelineContext } from \"@twick/timeline\";\nimport { CAPTION_PROPS } from \"../helpers/constant\";\n\ninterface SubtitleEntry {\n s: number;\n e: number;\n t: string;\n}\n\nexport const useSubtitlesPanel = () => {\n const [subtitles, setSubtitles] = useState<SubtitleEntry[]>([]);\n const subtitlesTrack = useRef<Track | null>(null);\n const { editor } = useTimelineContext();\n\n const fetchSubtitles = async () => {\n const editorSubtitlesTrack = editor.getSubtiltesTrack();\n if (editorSubtitlesTrack) {\n subtitlesTrack.current = editorSubtitlesTrack;\n setSubtitles(\n editorSubtitlesTrack.getElements().map((element) => ({\n s: element.getStart(),\n e: element.getEnd(),\n t: (element as CaptionElement).getText(),\n }))\n );\n }\n };\n\n useEffect(() => {\n fetchSubtitles();\n }, []);\n\n const checkSubtitlesTrack = () => {\n if (!subtitlesTrack.current) {\n subtitlesTrack.current = editor.addTrack(\"Subtitles\", \"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 subtitlesTrack.current?.setProps(props);\n }\n };\n\n const addSubtitle = () => {\n const newSubtitle: SubtitleEntry = { s: 0, e: 0, t: \"New Subtitle\" };\n if (subtitles.length > 0) {\n newSubtitle.s = subtitles[subtitles.length - 1].e;\n }\n newSubtitle.e = newSubtitle.s + 1;\n setSubtitles([...subtitles, newSubtitle]);\n checkSubtitlesTrack();\n const captionElement = new CaptionElement(\n newSubtitle.t,\n newSubtitle.s,\n newSubtitle.e\n );\n editor.addElementToTrack(subtitlesTrack.current as Track, captionElement);\n };\n\n const splitSubtitle = async (index: number) => {\n if (subtitlesTrack.current) {\n const element = subtitlesTrack.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 fetchSubtitles();\n }\n }\n };\n\n const deleteSubtitle = (index: number) => {\n setSubtitles(subtitles.filter((_, i) => i !== index));\n if (subtitlesTrack.current) {\n editor.removeElement(subtitlesTrack.current.getElements()[index]);\n }\n };\n\n const updateSubtitle = (index: number, subtitle: SubtitleEntry) => {\n setSubtitles(subtitles.map((sub, i) => (i === index ? subtitle : sub)));\n if (subtitlesTrack.current) {\n const element = subtitlesTrack.current.getElements()[\n index\n ] as CaptionElement;\n element.setText(subtitle.t);\n editor.updateElement(element);\n }\n };\n\n return {\n subtitles,\n addSubtitle,\n splitSubtitle,\n deleteSubtitle,\n updateSubtitle,\n };\n};\n","import { SubtitlesPanel } from \"../panel/subtitles-panel\";\nimport { useSubtitlesPanel } from \"../../hooks/use-subtitles-panel\";\n\nexport function SubtitlesPanelContainer() {\n const subtitlesPanelProps = useSubtitlesPanel();\n return <SubtitlesPanel {...subtitlesPanelProps} />;\n}","import React from \"react\";\nimport { Size, TrackElement } from \"@twick/timeline\";\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 { IconPanelContainer } from \"./icon-panel-container\";\nimport { RectPanelContainer } from \"./rect-panel-container\";\nimport { CirclePanelContainer } from \"./circle-panel-container\";\nimport { Wand2 } from \"lucide-react\";\nimport { SubtitlesPanelContainer } from \"./subtitles-panel-container\";\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}\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 subtitles. 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}: 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 switch (selectedTool) {\n case \"image\":\n return (\n <ImagePanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"audio\":\n return (\n <AudioPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"video\":\n return (\n <VideoPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"text\":\n return (\n <TextPanelContainer\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"icon\":\n return (\n <IconPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"rect\":\n return (\n <RectPanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"circle\":\n return (\n <CirclePanelContainer\n videoResolution={videoResolution}\n selectedElement={selectedElement}\n addElement={addNewElement}\n updateElement={updateElement}\n />\n );\n case \"subtitle\":\n return <SubtitlesPanelContainer />;\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","/**\n * PropsToolbar Component\n *\n * A vertical toolbar that provides quick access to different property sections\n * for the selected element. Displays icons for each section.\n *\n * @component\n * @param {Object} props\n * @param {TrackElement} props.selectedElement - The currently selected element to display properties for\n * @param {string} props.selectedProp - The currently selected property to display\n * @param {Function} props.setSelectedProp - The function to set the currently selected property\n *\n * @example\n * ```tsx\n * <PropsToolbar\n * selectedElement={someElement}\n * selectedProp={someProp}\n * setSelectedProp={someFunction}\n * />\n * ```\n */\n\nimport {\n Type,\n Image,\n Music,\n Infinity,\n Zap,\n MessageSquare,\n Captions,\n Plus,\n Settings,\n SparklesIcon,\n} from \"lucide-react\";\nimport type { ToolCategory } from \"../types\";\nimport {\n AudioElement,\n CaptionElement,\n CircleElement,\n IconElement,\n ImageElement,\n RectElement,\n TextElement,\n TrackElement,\n VideoElement,\n} from \"@twick/timeline\";\nimport { useEffect, useMemo } from \"react\";\n\nconst propsCategories: Map<string, ToolCategory> = new Map([\n [\n \"element-props\",\n {\n id: \"element-props\",\n name: \"Properties\",\n icon: \"Settings\",\n description: \"Element Properties\",\n },\n ],\n [\n \"animations\",\n {\n id: \"animations\",\n name: \"Animations\",\n icon: \"Zap\",\n description: \"Animations\",\n },\n ],\n [\n \"text-effects\",\n {\n id: \"text-effects\",\n name: \"Text Effects\",\n icon: \"SparklesIcon\",\n description: \"Text Effects\",\n },\n ],\n [\n \"color-effects\",\n {\n id: \"color-effects\",\n name: \"Color Effects\",\n icon: \"Image\",\n description: \"Color Effects\",\n },\n ],\n [\n \"playback-props\",\n {\n id: \"playback-props\",\n name: \"Playback Props\",\n icon: \"Music\",\n description: \"Playback Properties\",\n },\n ],\n [\n \"subtitle-style\",\n {\n id: \"subtitle-style\",\n name: \"Subtitle Style\",\n icon: \"MessageSquare\",\n description: \"Subtitle Style\",\n },\n ],\n [\n \"generate-subtitles\",\n {\n id: \"generate-subtitles\",\n name: \"Generate Subtitles\",\n icon: \"Subtitles\",\n description: \"Generate Subtitles\",\n },\n ],\n]);\n\nconst getIcon = (iconName: string) => {\n switch (iconName) {\n case \"Type\":\n return Type;\n case \"Infinity\":\n return Infinity;\n case \"Image\":\n return Image;\n case \"Music\":\n return Music;\n case \"Subtitles\":\n return Captions;\n case \"MessageSquare\":\n return MessageSquare;\n case \"Settings\":\n return Settings;\n case \"SparklesIcon\":\n return SparklesIcon;\n case \"Zap\":\n return Zap;\n default:\n return Plus;\n }\n};\n\nexport function PropsToolbar({\n selectedElement,\n selectedProp,\n setSelectedProp,\n}: {\n selectedElement: TrackElement | null;\n selectedProp: string;\n setSelectedProp: (prop: string) => void;\n}) {\n const availableSections = useMemo(() => {\n const sections: ToolCategory[] = [];\n if (selectedElement instanceof TextElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n sections.push(propsCategories.get(\"text-effects\")!);\n } else if (selectedElement instanceof ImageElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n sections.push(propsCategories.get(\"color-effects\")!);\n } else if (selectedElement instanceof VideoElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n sections.push(propsCategories.get(\"color-effects\")!);\n sections.push(propsCategories.get(\"playback-props\")!);\n sections.push(propsCategories.get(\"generate-subtitles\")!);\n } else if (selectedElement instanceof AudioElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"playback-props\")!);\n } else if (selectedElement instanceof CircleElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n } else if (selectedElement instanceof RectElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n } else if (selectedElement instanceof IconElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n } else if (selectedElement instanceof CaptionElement) {\n sections.push(propsCategories.get(\"element-props\")!);\n sections.push(propsCategories.get(\"animations\")!);\n sections.push(propsCategories.get(\"subtitle-style\")!);\n }\n return sections;\n }, [selectedElement]);\n\n useEffect(() => {\n if (availableSections?.length) {\n if (\n availableSections.map((section) => section.id).indexOf(selectedProp) ===\n -1\n ) {\n setSelectedProp(availableSections[0].id);\n }\n }\n }, [availableSections]);\n \n return (\n <div className=\"sidebar\">\n {/* Main Tools */}\n {availableSections.map((tool) => {\n const Icon = getIcon(tool.icon);\n const isSelected = selectedProp === tool.id;\n return (\n <div\n key={tool.id}\n onClick={() => setSelectedProp(tool.id)}\n className={`toolbar-btn ${isSelected ? \"active\" : \"\"}`}\n title={`${tool.name}${tool.shortcut ? ` (${tool.shortcut})` : \"\"}`}\n >\n <Icon className=\"icon-sm\" />\n <span className=\"props-toolbar-label\">{tool.name}</span>\n </div>\n );\n })}\n </div>\n );\n}\n","import type { PropertiesPanelProps } from \"../../types\";\n\nexport function ElementProps({ selectedElement, updateElement }: PropertiesPanelProps) {\n const elementProps = selectedElement?.getProps() || {};\n const {x, y, opacity, rotation} = elementProps;\n\n const handleUpdateElement = (props: Record<string, any>) => {\n if(selectedElement) {\n updateElement?.(selectedElement?.setProps({...elementProps,...props}));\n }\n }\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">All Properties</div>\n <div className=\"panel-section\">\n <label className=\"label-dark\">Position</label>\n <div className=\"flex-container\">\n <div>\n <label className=\"label-small\">X</label>\n <input\n type=\"number\"\n value={x ?? 0}\n onChange={(e) => handleUpdateElement({ x: Number(e.target.value)})}\n className=\"input-dark\"\n />\n </div>\n <div>\n <label className=\"label-small\">Y</label>\n <input\n type=\"number\"\n value={y ?? 0}\n onChange={(e) => handleUpdateElement({ y: Number(e.target.value)})}\n className=\"input-dark\"\n />\n </div>\n </div>\n </div>\n\n {/* Opacity */}\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 value={(opacity ?? 1) * 100}\n onChange={(e) => handleUpdateElement({ opacity: Number(e.target.value) / 100})}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{Math.round((opacity ?? 1) * 100)}%</span>\n </div>\n </div>\n\n {/* Rotation */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Rotation</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"360\"\n value={rotation ?? 0}\n onChange={(e) => handleUpdateElement({ rotation: Number(e.target.value)})}\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{rotation ?? 0}°</span>\n </div>\n </div>\n </div>\n );\n}\n","import { TEXT_EFFECTS } from \"@twick/video-editor\";\nimport { ElementTextEffect, TextElement } from \"@twick/timeline\";\nimport type { PropertiesPanelProps } from \"../../types\";\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 return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Text Effects</div>\n {/* Text Effect Selection */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Text Effect Type</label>\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 </div>\n\n {/* Text Effect Options */}\n {currentEffect && (\n <>\n {/* Delay */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Delay (seconds)</label>\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 </div>\n\n {/* Duration */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Duration (seconds)</label>\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 </div>\n\n {/* Buffer Time */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Buffer Time (seconds)</label>\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({ bufferTime: Number(e.target.value) })\n }\n className=\"input-dark\"\n />\n </div>\n </>\n )}\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 type { PropertiesPanelProps } from \"../../types\";\nexport function PlaybackPropsPanel({\n selectedElement,\n updateElement,\n}: PropertiesPanelProps) {\n const elementProps = selectedElement?.getProps() || {};\n const { volume } = elementProps;\n\n const handleUpdateElement = (props: Record<string, any>) => {\n if (selectedElement) {\n updateElement?.(selectedElement?.setProps({ ...elementProps, ...props }));\n }\n };\n return (\n <div className=\"panel-container\">\n <div className=\"panel-title\">Playback Properties</div>\n {/* Volume */}\n <div className=\"panel-section\">\n <label className=\"label-dark\">Volume</label>\n <div className=\"slider-container\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"3\"\n step={0.1}\n value={volume ?? 0}\n onChange={(e) =>\n handleUpdateElement({ volume: Number(e.target.value) })\n }\n className=\"slider-purple\"\n />\n <span className=\"slider-value\">{volume ?? 0}</span>\n </div>\n </div>\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 video = document.createElement(\"video\");\n video.preload = \"metadata\";\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 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 = () => reject(new Error(\"Failed to load video metadata\"));\n });\n};\n\nconst getThumbnail = async (videoUrl, seekTime = 0.1, playbackRate = 1) => {\n return new Promise((resolve, reject) => {\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 = 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 reject(new Error(`Failed to load video: ${video.error?.message || \"Unknown error\"}`));\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;\n }).catch(() => {\n video.currentTime = seekTime;\n });\n } else {\n video.currentTime = seekTime;\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};\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) {\n console.warn(`Invalid segment: start (${segment.s}) >= end (${segment.e})`);\n continue;\n }\n const volume = segment.volume ?? 1;\n if (volume <= 0) {\n console.warn(`Skipping muted segment: ${segment.src}`);\n continue;\n }\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 (error) {\n console.warn(`Failed to process segment: ${segment.src}`, error);\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 console.error(\"Error downloading file:\", 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 (error) {\n console.error(\"Fetch failed:\", error);\n return null;\n }\n};\n\nexport { blobUrlToFile, detectMediaTypeFromUrl, downloadFile, extractAudio, getAudioDuration, getImageDimensions, getObjectFitSize, getScaledDimensions, getThumbnail, 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 { ISubtitleGenerationPollingResponse } from \"../../types\";\n\nexport function GenerateSubtitlesPanel({\n selectedElement,\n addSubtitlesToTimeline,\n onGenerateSubtitles,\n getSubtitleStatus,\n}: {\n selectedElement: TrackElement;\n addSubtitlesToTimeline: (subtitles: { s: number; e: number; t: string }[]) => void;\n onGenerateSubtitles: (videoElement: VideoElement) => Promise<string | null>;\n getSubtitleStatus: (reqId: string) => Promise<ISubtitleGenerationPollingResponse>;\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 (!getSubtitleStatus) {\n return;\n }\n setPollingStatus(\"polling\");\n setIsGenerating(true);\n setErrorMessage(null);\n\n const poll = async () => {\n try {\n const response = await getSubtitleStatus(reqId);\n\n \n if (response.status === \"completed\") {\n stopPolling();\n setPollingStatus(\"success\");\n setIsGenerating(false);\n \n // Add subtitles to timeline\n addSubtitlesToTimeline(response.subtitles || []);\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 subtitles\");\n console.error(\"Error generating subtitles:\", response.error);\n }\n } catch (error) {\n stopPolling();\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(error instanceof Error ? error.message : \"Failed to get subtitle status\");\n console.error(\"Error polling for subtitles:\", error);\n }\n };\n\n // Poll immediately, then every 2 seconds\n await poll();\n pollingIntervalRef.current = setInterval(poll, 2000);\n };\n\n const handleGenerateSubtitles = async () => {\n if (!(selectedElement instanceof VideoElement)) {\n return;\n }\n\n const videoElement = selectedElement as VideoElement;\n \n\n try {\n const reqId = await onGenerateSubtitles(videoElement);\n if (!reqId) {\n setPollingStatus(\"error\");\n setIsGenerating(false);\n setErrorMessage(\"Failed to start subtitle generation\");\n console.error(\"Error generating subtitles: Failed to start subtitle 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 subtitle generation\");\n console.error(\"Error generating subtitles:\", 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 Subtitles 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 subtitles</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 subtitles... 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\">Subtitles 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 subtitles\"}</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Generate Button */}\n {!isLoading && (\n <div className=\"flex panel-section\">\n <button\n onClick={handleGenerateSubtitles}\n disabled={!containsAudio || isGenerating}\n className=\"btn-primary w-full\"\n >\n {isGenerating ? \"Generating...\" : \"Generate Subtitles\"}\n </button>\n </div>\n )}\n </div>\n );\n}\n","import { ElementProps } from \"../properties/element-props\";\nimport { TextEffects } from \"../properties/text-effects\";\nimport { Animation } from \"../properties/animation\";\nimport { VideoElement, type TrackElement } from \"@twick/timeline\";\nimport { PlaybackPropsPanel } from \"../properties/playback-props\";\nimport { GenerateSubtitlesPanel } from \"../properties/generate-subtitles\";\nimport { ISubtitleGenerationPollingResponse, SubtitleEntry } from \"../../types\";\n\ninterface PropertiesPanelContainerProps {\n selectedProp: string;\n selectedElement: TrackElement | null;\n updateElement: (element: TrackElement) => void;\n addSubtitlesToTimeline: (subtitles: SubtitleEntry[]) => void;\n onGenerateSubtitles: (videoElement: VideoElement) => Promise<string | null>;\n getSubtitleStatus: (reqId: string) => Promise<ISubtitleGenerationPollingResponse>;\n}\n\nexport function PropertiesPanelContainer({\n selectedProp,\n selectedElement,\n updateElement,\n addSubtitlesToTimeline,\n onGenerateSubtitles,\n getSubtitleStatus,\n}: PropertiesPanelContainerProps) {\n if (!selectedElement) {\n return (\n <div className=\"panel-container\">\n <div className=\"properties-header\">\n <h3 className=\"properties-title\">Select Element to see properties</h3>\n </div>\n </div>\n );\n }\n\n if (selectedElement.getType() === \"caption\") {\n return (\n <div className=\"panel-container\">\n <div className=\"properties-header\">\n <h3 className=\"properties-title\">Not available for sub-title</h3>\n </div>\n </div>\n );\n }\n \n return (\n <>\n {/* Element Properties */}\n {selectedProp === \"element-props\" && (\n <ElementProps\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Playback Properties */}\n {selectedProp === \"playback-props\" && (\n <PlaybackPropsPanel\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Text Effects */}\n {selectedProp === \"text-effects\" && (\n <TextEffects\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n\n {/* Animations */}\n {selectedProp === \"animations\" && (\n <Animation\n selectedElement={selectedElement}\n updateElement={updateElement}\n />\n )}\n {\n selectedProp === \"generate-subtitles\" && (\n <GenerateSubtitlesPanel\n selectedElement={selectedElement}\n addSubtitlesToTimeline={addSubtitlesToTimeline}\n onGenerateSubtitles={onGenerateSubtitles}\n getSubtitleStatus={getSubtitleStatus}\n />\n )\n }\n </>\n );\n}\n","import { ProjectJSON, useTimelineContext, VideoElement } from \"@twick/timeline\";\nimport { ISubtitleGenerationPollingResponse, StudioConfig, SubtitleEntry } from \"../types\";\nimport { loadFile, saveAsFile } from \"@twick/media-utils\";\nimport { useState } from \"react\";\n\nconst useStudioOperation = (studioConfig?: StudioConfig) => {\n const { editor, present } = useTimelineContext();\n const [projectName, setProjectName] = useState(\"\");\n const onLoadProject = async () => {\n let project: ProjectJSON;\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 console.log(\"Editor\", editor);\n editor.loadProject(project);\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: studioConfig.videoProps?.width,\n height: studioConfig.videoProps?.height,\n },\n });\n } else {\n alert(\"Export video not supported in demo mode\");\n }\n };\n\n\n\n /**\n * Generates subtitles using the new polling-based service\n * Returns a function that can be called to start the generation process\n */\n const onGenerateSubtitles = async (videoElement: VideoElement) => {\n // Use new polling-based service if available\n if (studioConfig?.subtitleGenerationService) {\n const service = studioConfig.subtitleGenerationService;\n const reqId = await service.generateSubtitles(videoElement, present as ProjectJSON);\n return reqId;\n }\n alert(\"Generate subtitles not supported in demo mode\");\n return null;\n };\n\n const addSubtitlesToTimeline = (subtitles: SubtitleEntry[]) => {\n const updatedProjectJSON = studioConfig?.subtitleGenerationService?.updateProjectWithSubtitles(subtitles);\n if (updatedProjectJSON) {\n editor.loadProject(updatedProjectJSON);\n }\n }\n\n const getSubtitleStatus = async (reqId: string) => {\n if (studioConfig?.subtitleGenerationService) {\n const service = studioConfig.subtitleGenerationService;\n return await service.getRequestStatus(reqId);\n }\n return {\n status: \"failed\",\n error: \"Subtitle generation service not found\",\n } as ISubtitleGenerationPollingResponse;\n }\n\n return { \n onLoadProject, \n onSaveProject, \n onExportVideo, \n onGenerateSubtitles,\n addSubtitlesToTimeline,\n getSubtitleStatus,\n };\n};\n\nexport default useStudioOperation;\n","import { ProjectJSON, useTimelineContext, VideoElement } from \"@twick/timeline\";\nimport {\n ISubtitleGenerationPollingResponse,\n StudioConfig,\n SubtitleEntry,\n} from \"../types\";\n\nconst useGenerateSubtitles = (studioConfig?: StudioConfig) => {\n const { editor, present } = useTimelineContext();\n /**\n * Generates subtitles using the new polling-based service\n * Returns a function that can be called to start the generation process\n */\n const onGenerateSubtitles = async (videoElement: VideoElement) => {\n // Use new polling-based service if available\n if (studioConfig?.subtitleGenerationService) {\n const service = studioConfig.subtitleGenerationService;\n const reqId = await service.generateSubtitles(\n videoElement,\n present as ProjectJSON\n );\n return reqId;\n }\n alert(\"Generate subtitles not supported in demo mode\");\n return null;\n };\n\n const addSubtitlesToTimeline = (subtitles: SubtitleEntry[]) => {\n const updatedProjectJSON =\n studioConfig?.subtitleGenerationService?.updateProjectWithSubtitles(\n subtitles\n );\n if (updatedProjectJSON) {\n editor.loadProject(updatedProjectJSON);\n }\n };\n\n const getSubtitleStatus = async (reqId: string) => {\n if (studioConfig?.subtitleGenerationService) {\n const service = studioConfig.subtitleGenerationService;\n return await service.getRequestStatus(reqId);\n }\n return {\n status: \"failed\",\n error: \"Subtitle generation service not found\",\n } as ISubtitleGenerationPollingResponse;\n };\n\n return {\n onGenerateSubtitles,\n addSubtitlesToTimeline,\n getSubtitleStatus,\n };\n};\n\nexport default useGenerateSubtitles;\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 { PropsToolbar } from \"./props-toolbar\";\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 useGenerateSubtitles from \"../hooks/use-generate-subtitles\";\n\nexport function TwickStudio({ studioConfig }: { studioConfig?: StudioConfig }) {\n const {\n selectedTool,\n setSelectedTool,\n selectedProp,\n setSelectedProp,\n selectedElement,\n addElement,\n updateElement,\n } = useStudioManager();\n const { videoResolution, setVideoResolution } = useTimelineContext();\n const {\n onLoadProject,\n onSaveProject,\n onExportVideo,\n } = useStudioOperation(studioConfig);\n\n const { onGenerateSubtitles, addSubtitlesToTimeline, getSubtitleStatus } =\n useGenerateSubtitles(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 },\n }),\n [videoResolution, studioConfig]\n );\n\n return (\n <MediaProvider>\n <div className=\"studio-container\">\n {/* Header */}\n <StudioHeader\n setVideoResolution={setVideoResolution}\n onLoadProject={onLoadProject}\n onSaveProject={onSaveProject}\n onExportVideo={onExportVideo}\n />\n {/* Main Content */}\n <div className=\"studio-content\">\n {/* Left Toolbar */}\n <Toolbar\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n />\n\n {/* Left Panel */}\n <ElementPanelContainer\n videoResolution={videoResolution}\n selectedTool={selectedTool}\n setSelectedTool={setSelectedTool}\n selectedElement={selectedElement}\n addElement={addElement}\n updateElement={updateElement}\n />\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 ?? 960,\n }}\n >\n <VideoEditor editorConfig={twickStudiConfig} />\n </div>\n </div>\n </main>\n\n {/* Left Panel */}\n <PropertiesPanelContainer\n selectedProp={selectedProp}\n selectedElement={selectedElement}\n updateElement={updateElement}\n addSubtitlesToTimeline={addSubtitlesToTimeline}\n onGenerateSubtitles={onGenerateSubtitles}\n getSubtitleStatus={getSubtitleStatus}\n />\n\n {/* Right Toolbar */}\n <PropsToolbar\n selectedElement={selectedElement}\n selectedProp={selectedProp}\n setSelectedProp={setSelectedProp}\n />\n </div>\n </div>\n </MediaProvider>\n );\n}\n"],"names":["forwardRef","createElement","__iconNode","getIcon","Icon","jsxs","jsx","useState","useEffect","orientation","useTimelineContext","useEditorManager","TrackElement","useRef","Track","BrowserMediaManager","createContext","useContext","VideoElement","AudioElement","ImageElement","config","useCallback","Wand2","AVAILABLE_TEXT_FONTS","TextElement","Loader2","IconElement","RectElement","CircleElement","CAPTION_STYLE","CaptionElement","SparklesIcon","useMemo","ElementTextEffect","TEXT_EFFECTS","Fragment","ANIMATIONS","ElementAnimation","CheckCircle2","XCircle"],"mappings":";;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,MAAM,cAAc,CAAC,WAAW,OAAO,QAAQ,sBAAsB,OAAO,EAAE,YAAW;AACzF,MAAM,cAAc,CAAC,WAAW,OAAO;AAAA,EACrC;AAAA,EACA,CAAC,OAAO,IAAI,OAAO,KAAK,GAAG,YAAW,IAAK,GAAG,YAAW;AAC3D;AACA,MAAM,eAAe,CAAC,WAAW;AAC/B,QAAM,YAAY,YAAY,MAAM;AACpC,SAAO,UAAU,OAAO,CAAC,EAAE,YAAW,IAAK,UAAU,MAAM,CAAC;AAC9D;AACA,MAAM,eAAe,IAAI,YAAY,QAAQ,OAAO,CAAC,WAAW,OAAO,UAAU;AAC/E,SAAO,QAAQ,SAAS,KAAK,UAAU,KAAI,MAAO,MAAM,MAAM,QAAQ,SAAS,MAAM;AACvF,CAAC,EAAE,KAAK,GAAG,EAAE,KAAI;AACjB,MAAM,cAAc,CAAC,UAAU;AAC7B,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,OAAO,KAAK,SAAS,UAAU,SAAS,SAAS;AACnE,aAAO;AAAA,IACT;AAAA,EACF;AACF;ACzBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,IAAI,oBAAoB;AAAA,EACtB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,eAAe;AAAA,EACf,gBAAgB;AAClB;ACjBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA,MAAM,OAAOA,MAAAA;AAAAA,EACX,CAAC;AAAA,IACC,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,cAAc;AAAA,IACd;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACP,GAAK,QAAQC,MAAAA;AAAAA,IACT;AAAA,IACA;AAAA,MACE;AAAA,MACA,GAAG;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa,sBAAsB,OAAO,WAAW,IAAI,KAAK,OAAO,IAAI,IAAI;AAAA,MAC7E,WAAW,aAAa,UAAU,SAAS;AAAA,MAC3C,GAAG,CAAC,YAAY,CAAC,YAAY,IAAI,KAAK,EAAE,eAAe,OAAM;AAAA,MAC7D,GAAG;AAAA,IACT;AAAA,IACI;AAAA,MACE,GAAG,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,MAAMA,MAAAA,cAAc,KAAK,KAAK,CAAC;AAAA,MAC3D,GAAG,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;AAAA,IACvD;AAAA,EACA;AACA;ACvCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA,MAAM,mBAAmB,CAAC,UAAU,aAAa;AAC/C,QAAM,YAAYD,MAAAA;AAAAA,IAChB,CAAC,EAAE,WAAW,GAAG,MAAK,GAAI,QAAQC,MAAAA,cAAc,MAAM;AAAA,MACpD;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT,UAAU,YAAY,aAAa,QAAQ,CAAC,CAAC;AAAA,QAC7C,UAAU,QAAQ;AAAA,QAClB;AAAA,MACR;AAAA,MACM,GAAG;AAAA,IACT,CAAK;AAAA,EACL;AACE,YAAU,cAAc,aAAa,QAAQ;AAC7C,SAAO;AACT;AC1BA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMC,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,OAAO,MAAM,QAAQ,MAAM,GAAG,KAAK,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK,UAAU;AAAA,EACvF,CAAC,QAAQ,EAAE,GAAG,kCAAkC,KAAK,SAAQ,CAAE;AACjE;AACA,MAAM,WAAW,iBAAiB,YAAYA,YAAU;ACbxD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,UAAU,EAAE,IAAI,MAAM,IAAI,MAAM,GAAG,MAAM,KAAK,UAAU;AAAA,EACzD,CAAC,QAAQ,EAAE,GAAG,iBAAiB,KAAK,SAAQ,CAAE;AAChD;AACA,MAAM,cAAc,iBAAiB,gBAAgBA,YAAU;ACb/D;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,UAAU,EAAE,IAAI,MAAM,IAAI,MAAM,GAAG,MAAM,KAAK,UAAU;AAAA,EACzD,CAAC,QAAQ,EAAE,GAAG,aAAa,KAAK,SAAQ,CAAE;AAAA,EAC1C,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,SAAQ,CAAE;AAC3C;AACA,MAAM,UAAU,iBAAiB,YAAYA,YAAU;ACdvD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa,CAAC,CAAC,UAAU,EAAE,IAAI,MAAM,IAAI,MAAM,GAAG,MAAM,KAAK,SAAQ,CAAE,CAAC;AAC9E,MAAM,SAAS,iBAAiB,UAAUA,YAAU;ACVpD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA,EAAE,GAAG,2EAA2E,KAAK,SAAQ;AAAA,EACjG;AAAA,EACE,CAAC,QAAQ,EAAE,GAAG,oBAAoB,KAAK,SAAQ,CAAE;AAAA,EACjD,CAAC,QAAQ,EAAE,GAAG,mBAAmB,KAAK,SAAQ,CAAE;AAAA,EAChD,CAAC,QAAQ,EAAE,GAAG,6CAA6C,KAAK,SAAQ,CAAE;AAC5E;AACA,MAAM,eAAe,iBAAiB,gBAAgBA,YAAU;AClBhE;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,SAAQ,CAAE;AAAA,EACzC,CAAC,QAAQ,EAAE,GAAG,6CAA6C,KAAK,SAAQ,CAAE;AAAA,EAC1E,CAAC,QAAQ,EAAE,GAAG,iBAAiB,KAAK,SAAQ,CAAE;AAChD;AACA,MAAM,WAAW,iBAAiB,YAAYA,YAAU;ACdxD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,8DAA8D,KAAK,SAAQ,CAAE;AAAA,EAC3F,CAAC,QAAQ,EAAE,GAAG,2BAA2B,KAAK,SAAQ,CAAE;AAC1D;AACA,MAAM,OAAO,iBAAiB,QAAQA,YAAU;ACbhD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,OAAO,MAAM,QAAQ,MAAM,GAAG,KAAK,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK,UAAU;AAAA,EACvF,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,KAAK,GAAG,KAAK,KAAK,UAAU;AAAA,EACtD,CAAC,QAAQ,EAAE,GAAG,6CAA6C,KAAK,SAAQ,CAAE;AAC5E;AACA,MAAM,QAAQ,iBAAiB,SAASA,YAAU;ACdlD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,gEAAgE,KAAK,SAAQ,CAAE;AAC/F;AACA,MAAM,WAAW,iBAAiB,YAAYA,YAAU;ACZxD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa,CAAC,CAAC,QAAQ,EAAE,GAAG,+BAA+B,KAAK,SAAQ,CAAE,CAAC;AACjF,MAAM,eAAe,iBAAiB,iBAAiBA,YAAU;ACVjE;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,iEAAiE,KAAK,SAAQ,CAAE;AAChG;AACA,MAAM,gBAAgB,iBAAiB,kBAAkBA,YAAU;ACZnE;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,mBAAmB,KAAK,SAAQ,CAAE;AAAA,EAChD,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,MAAM,GAAG,KAAK,KAAK,UAAU;AAAA,EACvD,CAAC,UAAU,EAAE,IAAI,MAAM,IAAI,MAAM,GAAG,KAAK,KAAK,SAAQ,CAAE;AAC1D;AACA,MAAM,QAAQ,iBAAiB,SAASA,YAAU;ACdlD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,MAAM,GAAG,KAAK,OAAO,KAAK,QAAQ,MAAM,IAAI,KAAK,KAAK,SAAQ,CAAE;AAAA,EAC9E,CAAC,QAAQ,EAAE,GAAG,KAAK,GAAG,KAAK,OAAO,KAAK,QAAQ,MAAM,IAAI,KAAK,KAAK,SAAQ,CAAE;AAC/E;AACA,MAAM,QAAQ,iBAAiB,SAASA,YAAU;ACblD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa,CAAC,CAAC,WAAW,EAAE,QAAQ,sBAAsB,KAAK,SAAQ,CAAE,CAAC;AAChF,MAAM,OAAO,iBAAiB,QAAQA,YAAU;ACVhD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,SAAQ,CAAE;AAAA,EACzC,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,SAAQ,CAAE;AAC3C;AACA,MAAM,OAAO,iBAAiB,QAAQA,YAAU;ACbhD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,QAAQ,EAAE,GAAG,6CAA6C,KAAK,SAAQ,CAAE;AAAA,EAC1E,CAAC,QAAQ,EAAE,GAAG,0BAA0B,KAAK,SAAQ,CAAE;AACzD;AACA,MAAM,OAAO,iBAAiB,QAAQA,YAAU;ACpBhD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,KAAK,GAAG,KAAK,KAAK,UAAU;AAAA,EACtD,CAAC,QAAQ,EAAE,GAAG,oBAAoB,KAAK,SAAQ,CAAE;AAAA,EACjD,CAAC,QAAQ,EAAE,GAAG,oBAAoB,KAAK,SAAQ,CAAE;AAAA,EACjD,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,MAAM,GAAG,KAAK,KAAK,UAAU;AAAA,EACvD,CAAC,QAAQ,EAAE,GAAG,oBAAoB,KAAK,SAAQ,CAAE;AACnD;AACA,MAAM,WAAW,iBAAiB,YAAYA,YAAU;AChBxD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,oBAAoB,KAAK,SAAQ,CAAE;AAAA,EACjD,CAAC,UAAU,EAAE,IAAI,MAAM,IAAI,MAAM,GAAG,KAAK,KAAK,SAAQ,CAAE;AAC1D;AACA,MAAM,SAAS,iBAAiB,UAAUA,YAAU;ACbpD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,UAAU,EAAE,IAAI,MAAM,IAAI,MAAM,GAAG,KAAK,KAAK,SAAQ,CAAE;AAC1D;AACA,MAAM,WAAW,iBAAiB,YAAYA,YAAU;ACnBxD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,QAAQ,EAAE,GAAG,WAAW,KAAK,SAAQ,CAAE;AAAA,EACxC,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,SAAQ,CAAE;AAAA,EACzC,CAAC,QAAQ,EAAE,GAAG,WAAW,KAAK,SAAQ,CAAE;AAAA,EACxC,CAAC,QAAQ,EAAE,GAAG,WAAW,KAAK,SAAQ,CAAE;AAC1C;AACA,MAAM,WAAW,iBAAiB,YAAYA,YAAU;ACtBxD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,OAAO,MAAM,QAAQ,MAAM,GAAG,KAAK,GAAG,KAAK,IAAI,KAAK,KAAK,SAAQ,CAAE;AAChF;AACA,MAAM,SAAS,iBAAiB,UAAUA,YAAU;ACZpD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,WAAW,KAAK,SAAQ,CAAE;AAAA,EACxC,CAAC,QAAQ,EAAE,GAAG,yCAAyC,KAAK,SAAQ,CAAE;AAAA,EACtE,CAAC,QAAQ,EAAE,GAAG,sCAAsC,KAAK,SAAQ,CAAE;AAAA,EACnE,CAAC,QAAQ,EAAE,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,KAAK,SAAQ,CAAE;AAAA,EAClE,CAAC,QAAQ,EAAE,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,KAAK,QAAO,CAAE;AACnE;AACA,MAAM,SAAS,iBAAiB,WAAWA,YAAU;AChBrD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,SAAQ,CAAE;AAAA,EACzC,CAAC,QAAQ,EAAE,GAAG,2CAA2C,KAAK,SAAQ,CAAE;AAAA,EACxE,CAAC,QAAQ,EAAE,GAAG,WAAW,KAAK,SAAQ,CAAE;AAC1C;AACA,MAAM,OAAO,iBAAiB,QAAQA,YAAU;ACdhD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,SAAQ,CAAE;AAAA,EACzC,CAAC,QAAQ,EAAE,GAAG,iBAAiB,KAAK,SAAQ,CAAE;AAAA,EAC9C,CAAC,QAAQ,EAAE,GAAG,6CAA6C,KAAK,SAAQ,CAAE;AAC5E;AACA,MAAM,SAAS,iBAAiB,UAAUA,YAAU;ACdpD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,QAAQ,EAAE,GAAG,KAAK,GAAG,KAAK,OAAO,MAAM,QAAQ,MAAM,IAAI,KAAK,KAAK,SAAQ,CAAE;AAChF;AACA,MAAM,QAAQ,iBAAiB,SAASA,YAAU;ACnBlD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,QAAQ,EAAE,GAAG,uBAAuB,KAAK,SAAQ,CAAE;AAAA,EACpD,CAAC,QAAQ,EAAE,GAAG,qCAAqC,KAAK,SAAQ,CAAE;AACpE;AACA,MAAM,UAAU,iBAAiB,YAAYA,YAAU;ACpBvD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,QAAQ,EAAE,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,KAAK,SAAQ,CAAE;AAAA,EACjE,CAAC,QAAQ,EAAE,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,KAAK,SAAQ,CAAE;AACnE;AACA,MAAM,UAAU,iBAAiB,YAAYA,YAAU;ACpBvD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,eAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,QAAQ,EAAE,GAAG,aAAa,KAAK,SAAQ,CAAE;AAAA,EAC1C,CAAC,QAAQ,EAAE,GAAG,UAAU,KAAK,SAAQ,CAAE;AAAA,EACvC,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,SAAQ,CAAE;AAAA,EACzC,CAAC,QAAQ,EAAE,GAAG,WAAW,KAAK,SAAQ,CAAE;AAAA,EACxC,CAAC,QAAQ,EAAE,GAAG,UAAU,KAAK,SAAQ,CAAE;AAAA,EACvC,CAAC,QAAQ,EAAE,GAAG,aAAa,KAAK,SAAQ,CAAE;AAAA,EAC1C,CAAC,QAAQ,EAAE,GAAG,WAAW,KAAK,SAAQ,CAAE;AAC1C;AACA,MAAM,eAAe,iBAAiB,iBAAiBA,YAAU;ACzBjE;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAM,aAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AACA;AACA,MAAM,MAAM,iBAAiB,OAAO,UAAU;ACgB9C,MAAM,iBAAiC;AAAA,EACrC,EAAE,IAAI,SAAS,MAAM,SAAS,MAAM,SAAS,aAAa,QAAA;AAAA,EAC1D,EAAE,IAAI,SAAS,MAAM,SAAS,MAAM,SAAS,aAAa,QAAA;AAAA,EAC1D,EAAE,IAAI,SAAS,MAAM,SAAS,MAAM,SAAS,aAAa,QAAA;AAAA,EAC1D,EAAE,IAAI,QAAQ,MAAM,QAAQ,MAAM,QAAQ,aAAa,qBAAqB,UAAU,IAAA;AAAA,EACtF,EAAE,IAAI,QAAQ,MAAM,SAAS,MAAM,QAAQ,aAAa,gBAAgB,UAAU,IAAA;AAAA,EAClF,EAAE,IAAI,UAAU,MAAM,UAAU,MAAM,UAAU,aAAa,kBAAkB,UAAU,IAAA;AAAA,EACzF,EAAE,IAAI,QAAQ,MAAM,QAAQ,MAAM,QAAQ,aAAa,eAAA;AAAA,EACvD,EAAE,IAAI,YAAY,MAAM,aAAa,MAAM,iBAAiB,aAAa,oBAAoB,UAAU,IAAA;AACzG;AAEA,MAAMC,YAAU,CAAC,aAAqB;AACpC,UAAQ,UAAA;AAAA,IACN,KAAK;AAAQ,aAAO;AAAA,IACpB,KAAK;AAAQ,aAAO;AAAA,IACpB,KAAK;AAAQ,aAAO;AAAA,IACpB,KAAK;AAAU,aAAO;AAAA,IACtB,KAAK;AAAU,aAAO;AAAA,IACtB,KAAK;AAAS,aAAO;AAAA,IACrB,KAAK;AAAS,aAAO;AAAA,IACrB,KAAK;AAAS,aAAO;AAAA,IACrB,KAAK;AAAU,aAAO;AAAA,IACtB,KAAK;AAAQ,aAAO;AAAA,IACpB,KAAK;AAAiB,aAAO;AAAA,IAC7B;AAAS,aAAO;AAAA,EAAA;AAEpB;AAEO,SAAS,QAAQ,EAAE,cAAc,mBAAsF;AAE5H,QAAM,mBAAmB,CAAC,WAAmB;AAC3C,oBAAgB,MAAM;AAAA,EACxB;AAEA,wCACG,OAAA,EAAI,WAAU,WAEZ,UAAA,eAAe,IAAI,CAAC,SAAS;AAC5B,UAAMC,QAAOD,UAAQ,KAAK,IAAI;AAC9B,UAAM,aAAa,iBAAiB,KAAK;AAEzC,WACEE,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QAEC,SAAS,MAAM,iBAAiB,KAAK,EAAE;AAAA,QACvC,WAAW,eAAe,aAAa,WAAW,EAAE;AAAA,QACpD,OAAO,GAAG,KAAK,IAAI,GAAG,KAAK,WAAW,KAAK,KAAK,QAAQ,MAAM,EAAE;AAAA,QAEhE,UAAA;AAAA,UAAAC,2BAAAA,IAACF,OAAA,EAAK,WAAU,UAAA,CAAU;AAAA,UAC1BE,2BAAAA,IAAC,QAAA,EAAK,WAAU,iBACb,eAAK,KAAA,CACR;AAAA,QAAA;AAAA,MAAA;AAAA,MARK,KAAK;AAAA,IAAA;AAAA,EAWhB,CAAC,EAAA,CACH;AAEJ;AC/DO,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAyB;AACvB,QAAM,CAAC,aAAa,cAAc,IAAIC,MAAAA;AAAAA,IACpC;AAAA,EAAA;AAGFC,QAAAA,UAAU,MAAM;AACd,UAAMC,eAAc,aAAa,QAAQ,aAAa;AACtD,QAAIA,cAAa;AACf,qBAAeA,YAAwC;AAAA,IACzD;AAAA,EACF,GAAG,CAAA,CAAE;AAELD,QAAAA,UAAU,MAAM;AACd,QAAI,gBAAgB,cAAc;AAChC,mBAAa,QAAQ,eAAe,YAAY;AAChD,yBAAmB,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,IACjD,OAAO;AACL,mBAAa,QAAQ,eAAe,UAAU;AAC9C,yBAAmB,EAAE,OAAO,KAAK,QAAQ,MAAM;AAAA,IACjD;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAEhB,SACEH,2BAAAA,KAAC,UAAA,EAAO,WAAU,UAChB,UAAA;AAAA,IAAAC,2BAAAA,IAAC,SAAI,WAAU,kBACb,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,cAAA,EAAa,WAAU,wBAAA,CAAwB;AAAA,MAChDA,2BAAAA,IAAC,MAAA,EAAG,WAAU,iBAAgB,UAAA,eAAA,CAE9B;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,IACAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,MAAAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAM;AAAA,UACN,SAAS;AAAA,UAET,UAAA;AAAA,YAAAC,2BAAAA,IAAC,MAAA,EAAK,WAAU,UAAA,CAAU;AAAA,YAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAG9BD,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAM;AAAA,UACN,SAAS;AAAA,UAET,UAAA;AAAA,YAAAC,2BAAAA,IAAC,MAAA,EAAK,WAAU,UAAA,CAAU;AAAA,YAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAG9BD,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAM;AAAA,UACN,SAAS;AAAA,UAET,UAAA;AAAA,YAAAC,2BAAAA,IAAC,UAAA,EAAS,WAAU,UAAA,CAAU;AAAA,YAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAElC,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AChEO,MAAM,mBAAmB,MAAM;AACpC,QAAM,CAAC,cAAc,eAAe,IAAIC,MAAAA,SAAS,eAAe;AAEhE,QAAM,EAAE,aAAA,IAAiBG,4BAAA;AAEzB,QAAM,EAAE,YAAY,cAAA,IAAkBC,6BAAA;AAEtC,QAAM,kBACJ,wBAAwBC,SAAAA,eAAe,eAAe;AAExD,QAAM,CAAC,cAAc,eAAe,IAAIL,MAAAA,SAAiB,MAAM;AAE/D,QAAM,gBAAgBM,MAAAA,OAAO,KAAK;AAgBlCL,QAAAA,UAAU,MAAM;AACd,QAAI,wBAAwBI,SAAAA,cAAc;AACxC,sBAAgB,aAAa,SAAS;AACtC,oBAAc,UAAU;AAAA,IAC1B,WAAW,wBAAwBE,SAAAA,MAAO;AAAA,SAEnC;AACL,sBAAgB,OAAO;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,YAAY,CAAC;AAEjB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AC1EA,MAAM,yBAAN,MAAM,uBAAsB;AAAA,EAKhB,cAAc;AAAA,EAAC;AAAA,EAEvB,OAAc,cAAmC;AAC7C,QAAI,CAAC,uBAAsB,UAAU;AACjC,6BAAsB,WAAW,IAAIC,gCAAA;AAAA,IACzC;AACA,WAAO,uBAAsB;AAAA,EACjC;AAAA,EAEA,aAAoB,qBAAoC;AAEpD,QAAI,uBAAsB,eAAe;AACrC;AAAA,IACJ;AAGA,QAAI,uBAAsB,uBAAuB;AAC7C,YAAM,uBAAsB;AAC5B;AAAA,IACJ;AAIA,QAAI;AACJ,QAAI;AAEJ,2BAAsB,wBAAwB,IAAI,QAAc,CAAC,SAAS,WAAW;AACjF,uBAAiB;AACjB,sBAAgB;AAAA,IACpB,CAAC;AAGD,KAAC,YAAY;AACT,UAAI;AACA,cAAM,uBAAsB,qBAAA;AAC5B,+BAAsB,gBAAgB;AACtC,uBAAA;AAAA,MACJ,SAAS,OAAO;AAEZ,+BAAsB,wBAAwB;AAC9C,gBAAQ,MAAM,qCAAqC,KAAK;AACxD,sBAAe,KAAK;AAAA,MACxB;AAAA,IACJ,GAAA;AAEA,WAAO,uBAAsB;AAAA,EACjC;AAAA,EAEA,aAAqB,uBAAsC;AACvD,UAAM,UAAU,uBAAsB,YAAA;AAGtC,UAAM,gBAAgB;AAAA,MAClB;AAAA,QACI,MAAM;AAAA,QACN,KAAK;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,QAAA;AAAA,MACZ;AAAA,MAEJ;AAAA,QACI,MAAM;AAAA,QACN,KAAK;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,QAAA;AAAA,MACZ;AAAA,IACJ;AAIJ,UAAM,gBAAgB;AAAA,MAClB;AAAA,QACI,MAAM;AAAA,QACN,KAAK;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,QAAA;AAAA,MACZ;AAAA,MAEJ;AAAA,QACI,MAAM;AAAA,QACN,KAAK;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,QAAA;AAAA,MACZ;AAAA,IACJ;AAIJ,UAAM,gBAAgB;AAAA,MAClB;AAAA,QACI,MAAM;AAAA,QACN,KAAK;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,QAAA;AAAA,MACZ;AAAA,MAEJ;AAAA,QACI,MAAM;AAAA,QACN,KAAK;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,QAAA;AAAA,MACZ;AAAA,IACJ;AAGJ,QAAI;AAEA,YAAM,iBAAiB,MAAM,QAAQ,OAAO;AAAA,QACxC,MAAM;AAAA,QACN,OAAO;AAAA,MAAA,CACV;AAGD,YAAM,oBAAoB,IAAI,IAAI,eAAe,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AAClE,YAAM,cAAc,cAAc;AAAA,QAC9B,CAAC,UAAU,CAAC,kBAAkB,IAAI,MAAM,GAAG;AAAA,MAAA;AAI/C,UAAI,YAAY,SAAS,GAAG;AAExB,cAAM,aAAa,MAAM,QAAQ,OAAO;AAAA,UACpC,MAAM;AAAA,UACN,OAAO;AAAA,QAAA,CACV;AACD,cAAM,iBAAiB,IAAI,IAAI,WAAW,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AAC3D,cAAM,mBAAmB,YAAY;AAAA,UACjC,CAAC,UAAU,CAAC,eAAe,IAAI,MAAM,GAAG;AAAA,QAAA;AAG5C,YAAI,iBAAiB,SAAS,GAAG;AAC7B,gBAAM,QAAQ,SAAS,gBAAgB;AACvC,kBAAQ,IAAI,SAAS,iBAAiB,MAAM,oCAAoC;AAAA,QACpF;AAAA,MACJ;AAGA,YAAM,iBAAiB,MAAM,QAAQ,OAAO;AAAA,QACxC,MAAM;AAAA,QACN,OAAO;AAAA,MAAA,CACV;AAGD,YAAM,oBAAoB,IAAI,IAAI,eAAe,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC;AACtE,YAAM,cAAc,cAAc;AAAA,QAC9B,CAAC,UAAU,CAAC,kBAAkB,IAAI,MAAM,GAAG;AAAA,MAAA;AAI/C,UAAI,YAAY,SAAS,GAAG;AAExB,cAAM,aAAa,MAAM,QAAQ,OAAO;AAAA,UACpC,MAAM;AAAA,UACN,OAAO;AAAA,QAAA,CACV;AACD,cAAM,iBAAiB,IAAI,IAAI,WAAW,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC;AAC/D,cAAM,mBAAmB,YAAY;AAAA,UACjC,CAAC,UAAU,CAAC,eAAe,IAAI,MAAM,GAAG;AAAA,QAAA;AAG5C,YAAI,iBAAiB,SAAS,GAAG;AAC7B,gBAAM,QAAQ,SAAS,gBAAgB;AACvC,kBAAQ,IAAI,SAAS,iBAAiB,MAAM,oCAAoC;AAAA,QACpF;AAAA,MACJ;AAGA,YAAM,iBAAiB,MAAM,QAAQ,OAAO;AAAA,QACxC,MAAM;AAAA,QACN,OAAO;AAAA,MAAA,CACV;AAGD,YAAM,oBAAoB,IAAI,IAAI,eAAe,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AAClE,YAAM,cAAc,cAAc;AAAA,QAC9B,CAAC,UAAU,CAAC,kBAAkB,IAAI,MAAM,GAAG;AAAA,MAAA;AAI/C,UAAI,YAAY,SAAS,GAAG;AAExB,cAAM,aAAa,MAAM,QAAQ,OAAO;AAAA,UACpC,MAAM;AAAA,UACN,OAAO;AAAA,QAAA,CACV;AACD,cAAM,iBAAiB,IAAI,IAAI,WAAW,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AAC3D,cAAM,mBAAmB,YAAY;AAAA,UACjC,CAAC,UAAU,CAAC,eAAe,IAAI,MAAM,GAAG;AAAA,QAAA;AAG5C,YAAI,iBAAiB,SAAS,GAAG;AAC7B,gBAAM,QAAQ,SAAS,gBAAgB;AACvC,kBAAQ,IAAI,SAAS,iBAAiB,MAAM,yCAAyC;AAAA,QACzF;AAAA,MACJ;AAAA,IACJ,SAAS,OAAO;AAEZ,YAAM;AAAA,IACV;AAAA,EACJ;AACJ;AAxNI,cADE,wBACa,YAAuC;AACtD,cAFE,wBAEa,yBAA8C;AAC7D,cAHE,wBAGa,iBAAgB;AAHnC,IAAM,wBAAN;AA4NO,MAAM,kBAAkB,MAAM,sBAAsB,YAAA;AAGpD,MAAM,0BAA0B,MAAM,sBAAsB,mBAAA;AC7NnE,MAAM,aAA0C;AAAA,EAC9C,OAAO,CAAC,OAAO,QAAQ,OAAO,OAAO,OAAO,MAAM;AAAA,EAClD,OAAO,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM;AAAA,EACjD,OAAO,CAAC,OAAO,QAAQ,OAAO,OAAO,QAAQ,KAAK;AACpD;AAEA,SAAS,WAAW,KAAa;AAC/B,MAAI;AAEF,QAAI,IAAI,GAAG;AACX,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,YAAY,KAAa,MAAiB;AACjD,QAAM,YAAY,MAAM;AACtB,QAAI;AACF,aAAO,IAAI,IAAI,GAAG,EAAE,SAAS,YAAA;AAAA,IAC/B,QAAQ;AACN,aAAO,IAAI,YAAA;AAAA,IACb;AAAA,EACF,GAAA;AACA,QAAM,MAAM,SAAS,MAAM,GAAG,EAAE,SAAS;AACzC,SAAO,WAAW,IAAI,EAAE,SAAS,GAAG;AACtC;AAIA,SAAwB,SAAS;AAAA,EAC/B;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,KAAK,MAAM,IAAIR,MAAAA,SAAS,EAAE;AACjC,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAiB,EAAE;AAE7C,QAAM,SAAS,YAAY;AACzB,UAAM,UAAU,IAAI,KAAA;AACpB,QAAI,CAAC,QAAS;AAEd,QAAI,CAAC,WAAW,OAAO,GAAG;AACxB,eAAS,mBAAmB;AAC5B;AAAA,IACF;AAEA,QAAI,CAAC,YAAY,SAAS,IAAI,GAAG;AAC/B,eAAS,iBAAiB,IAAI,KAAK,WAAW,IAAI,EAAE,KAAK,IAAI,CAAC,GAAG;AACjE;AAAA,IACF;AAEA,aAAS,EAAE;AAEX,aAAS,OAAO;AAChB,WAAO,EAAE;AAAA,EACX;AAEA,QAAM,YAA0D,CAAC,MAAM;AACrE,QAAI,EAAE,QAAQ,SAAS;AACrB,QAAE,eAAA;AACF,WAAK,OAAA;AAAA,IACP;AAAA,EACF;AAEA,yCACG,OAAA,EACC,UAAA;AAAA,IAAAF,2BAAAA,KAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,MAAAC,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,aAAa,SAAS,IAAI;AAAA,UAC1B,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,OAAO,EAAE,OAAO,KAAK;AAAA,UACtC;AAAA,UACA,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAEZA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,SAAS,MAAM,KAAK,OAAA;AAAA,UACpB,cAAY,OAAO,IAAI;AAAA,UAEvB,UAAAA,2BAAAA,IAAC,MAAA,EAAK,MAAM,GAAA,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,IAClB,GACF;AAAA,IACC,QAAQA,2BAAAA,IAAC,QAAA,EAAK,WAAU,cAAc,iBAAM,IAAU;AAAA,EAAA,GACzD;AAEJ;AC1EA,MAAM,oBAAgC;AAAA,EACpC,OAAO,CAAA;AAAA,EACP,aAAa;AAAA,EACb,WAAW;AACb;AAEA,MAAM,eAAeU,MAAAA,cAAuC,IAAI;AAEzD,SAAS,cAAc,EAAE,YAAqC;AACnE,QAAM,CAAC,YAAY,aAAa,IAAIT,MAAAA,SAAqB,iBAAiB;AAC1E,QAAM,CAAC,YAAY,aAAa,IAAIA,MAAAA,SAAqB,iBAAiB;AAC1E,QAAM,CAAC,YAAY,aAAa,IAAIA,MAAAA,SAAqB,iBAAiB;AAC1E,QAAM,eAAe,gBAAA;AAErB,QAAM,oBAAoB,CAAC,SAA+D;AACxF,YAAQ,MAAA;AAAA,MACN,KAAK;AACH,eAAO,CAAC,YAAY,aAAa;AAAA,MACnC,KAAK;AACH,eAAO,CAAC,YAAY,aAAa;AAAA,MACnC,KAAK;AACH,eAAO,CAAC,YAAY,aAAa;AAAA,IAAA;AAAA,EAEvC;AAEA,QAAM,YAAY,OAAO,MAAiB,UAAkB;AAC1D,UAAM,CAAC,OAAO,QAAQ,IAAI,kBAAkB,IAAI;AAEhD,aAAS,EAAE,GAAG,OAAO,WAAW,MAAM;AACtC,QAAI;AACF,YAAM,UAAU,MAAM,aAAa,OAAO;AAAA,QACxC;AAAA,QACA;AAAA,MAAA,CACD;AACD,eAAS;AAAA,QACP,OAAO;AAAA,QACP,aAAa;AAAA,QACb,WAAW;AAAA,MAAA,CACZ;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,MAAM,iBAAiB,IAAI,WAAW,KAAK;AACnD,eAAS;AAAA,QACP,GAAG;AAAA,QACH,WAAW;AAAA,MAAA,CACZ;AAAA,IACH;AAAA,EACF;AAGAC,QAAAA,UAAU,MAAM;AACd,UAAM,aAAa,YAAY;AAE7B,YAAM,wBAAA;AAEN,gBAAU,SAAS,EAAE;AACrB,gBAAU,SAAS,EAAE;AACrB,gBAAU,SAAS,EAAE;AAAA,IACvB;AACA,eAAA;AAAA,EACF,GAAG,CAAA,CAAE;AAEL,QAAM,iBAAiB,CAAC,MAAiB,UAAkB;AACzD,UAAM,CAAC,OAAO,QAAQ,IAAI,kBAAkB,IAAI;AAChD,aAAS,EAAE,GAAG,OAAO,aAAa,OAAO;AACzC,cAAU,MAAM,KAAK;AAAA,EACvB;AAEA,QAAM,UAAU,CAAC,MAAiB,YAAuB;AACvD,UAAM,CAAC,OAAO,QAAQ,IAAI,kBAAkB,IAAI;AAChD,aAAS;AAAA,MACP,GAAG;AAAA,MACH,OAAO,CAAC,GAAG,MAAM,OAAO,OAAO;AAAA,IAAA,CAChC;AAAA,EACH;AAEA,SACEF,2BAAAA;AAAAA,IAAC,aAAa;AAAA,IAAb;AAAA,MACC,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAGD;AAAA,IAAA;AAAA,EAAA;AAGP;AAEO,SAAS,SAAS,MAAiB;AACxC,QAAM,UAAUW,MAAAA,WAAW,YAAY;AACvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAEA,QAAM,QAAQ,QAAQ,GAAG,IAAI,OAAO;AACpC,SAAO;AAAA,IACL,OAAO,MAAM;AAAA,IACb,aAAa,MAAM;AAAA,IACnB,WAAW,MAAM;AAAA,IACjB,gBAAgB,CAAC,UAAkB,QAAQ,eAAe,MAAM,KAAK;AAAA,IACrE,SAAS,CAAC,SAAoB,QAAQ,QAAQ,MAAM,IAAI;AAAA,EAAA;AAE5D;AClGA,MAAM,eAAe;AAAA,EACnB,OAAO;AAAA,IACL,iBAAiB,CAAC,SAAS;AAAA,IAC3B,eAAe,CAAC,KAAa,eAC3B,IAAIC,SAAAA,aAAa,KAAK,UAAU;AAAA,IAClC,eAAe,OAAO,SAAuB,QAAgB;AAC3D,UAAI,mBAAmBA,SAAAA,cAAc;AACnC,gBAAQ,OAAO,GAAG;AAClB,cAAM,QAAQ,gBAAA;AAAA,MAChB;AAAA,IACF;AAAA,EAAA;AAAA,EAEF,OAAO;AAAA,IACL,iBAAiB,CAAC,SAAS;AAAA,IAC3B,eAAe,CAAC,KAAa,gBAAsB,IAAIC,SAAAA,aAAa,GAAG;AAAA,IACvE,eAAe,OAAO,SAAuB,QAAgB;AAC3D,UAAI,mBAAmBA,SAAAA,cAAc;AACnC,gBAAQ,OAAO,GAAG;AAClB,cAAM,QAAQ,gBAAA;AAAA,MAChB;AAAA,IACF;AAAA,EAAA;AAAA,EAEF,OAAO;AAAA,IACL,iBAAiB,CAAC,SAAS;AAAA,IAC3B,eAAe,CAAC,KAAa,eAC3B,IAAIC,SAAAA,aAAa,KAAK,UAAU;AAAA,IAClC,eAAe,OAAO,SAAuB,QAAgB;AAC3D,UAAI,mBAAmBA,SAAAA,cAAc;AACnC,gBAAQ,OAAO,GAAG;AAClB,cAAM,QAAQ,gBAAA;AAAA,MAChB;AAAA,IACF;AAAA,EAAA;AAEJ;AAEO,MAAM,gBAAgB,CAC3B,MACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AACF,GAKA,oBACwC;AACxC,QAAM,EAAE,OAAO,aAAa,gBAAgB,SAAS,UAAA,IACnD,SAAS,IAAI;AACf,QAAM,eAAe,gBAAA;AAErB,QAAM,kBAAkB,OAAO,MAAiB,aAAuB;AACrE,UAAMC,UAAS,aAAa,IAAI;AAChC,QAAI,UAAU;AACZ,YAAM,UAAUA,QAAO,cAAc,KAAK,KAAK,eAAe;AAC9D,iBAAW,OAAO;AAAA,IACpB,OAAO;AACL,UAAI,iBAAiB;AACnB,cAAMA,QAAO,cAAc,iBAAiB,KAAK,GAAG;AACpD,sBAAc,eAAe;AAAA,MAC/B,OAAO;AACL,cAAM,UAAUA,QAAO,cAAc,KAAK,KAAK,eAAe;AAC9D,mBAAW,OAAO;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAAmB,OAAO,aAG1B;AACJ,UAAM,cAAc,MAAM,SAAS,KAAK,YAAA;AACxC,UAAM,UAAU,MAAM,aAAa,QAAQ;AAAA,MACzC,MAAM,SAAS,KAAK;AAAA,MACpB,KAAK,SAAS;AAAA,MACd;AAAA,MACA;AAAA,MACA,UAAU;AAAA,QACR,MAAM,SAAS,KAAK;AAAA,QACpB,MAAM,SAAS,KAAK;AAAA,QACpB,MAAM,SAAS,KAAK;AAAA,MAAA;AAAA,IACtB,CACD;AACD,YAAQ,OAAO;AAAA,EACjB;AAEA,QAAM,SAAS,aAAa,IAAI;AAChC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,OAAO;AAAA,EAAA;AAE5B;AC9GO,MAAM,kBAAkB,MAA+C;AAC5E,QAAM,CAAC,cAAc,eAAe,IAAId,MAAAA,SAAwB,IAAI;AACpE,QAAM,WAAWM,MAAAA,OAAgC,IAAI;AAGrDL,QAAAA,UAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,SAAS,SAAS;AACpB,iBAAS,QAAQ,MAAA;AACjB,iBAAS,UAAU;AAAA,MACrB;AAAA,IACF;AAAA,EACF,GAAG,CAAA,CAAE;AAEL,QAAM,eAAec,MAAAA,YAAY,MAAM;AACrC,QAAI,SAAS,SAAS;AACpB,eAAS,QAAQ,MAAA;AACjB,eAAS,UAAU;AAAA,IACrB;AACA,oBAAgB,IAAI;AAAA,EACtB,GAAG,CAAA,CAAE;AAEL,QAAM,kBAAkBA,kBAAY,CAAC,SAAoB;AAEvD,QAAI,iBAAiB,KAAK,IAAI;AAC5B,mBAAA;AACA;AAAA,IACF;AAGA,iBAAA;AAGA,UAAM,QAAQ,IAAI,MAAM,KAAK,GAAG;AAChC,UAAM,iBAAiB,SAAS,YAAY;AAC5C,UAAM,KAAA;AACN,aAAS,UAAU;AACnB,oBAAgB,KAAK,EAAE;AAAA,EACzB,GAAG,CAAC,cAAc,YAAY,CAAC;AAE/B,SAAO;AAAA,IACL;AAAA,IACA,cAAc,SAAS;AAAA,IACvB;AAAA,IACA;AAAA,EAAA;AAEJ;ACvBO,MAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AACF,MAAuB;AACrB,QAAM,EAAE,cAAc,gBAAA,IAAoB,gBAAA;AAC1C,SACEjB,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,iBAAa;AAAA,IAG1CA,2BAAAA,IAAC,OAAA,EAAI,WAAU,iBACb,UAAAA,2BAAAA,IAAC,YAAS,MAAK,SAAQ,UAAU,SAAA,CAAU,EAAA,CAC7C;AAAA,IAeAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,cACX,WAAA,SAAS,CAAA,GAAI,IAAI,CAAC,SAAA;;AAClBA,0CAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YAEC,eAAe,MAAM,aAAa,IAAI;AAAA,YACtC,WAAU;AAAA,YAGV,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,sBAEb,UAAA;AAAA,cAAAC,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,SAAS,CAAC,MAAM;AACd,sBAAE,gBAAA;AACF,oCAAgB,IAAI;AAAA,kBACtB;AAAA,kBACA,WAAU;AAAA,kBAET,UAAA,iBAAiB,KAAK,KACrBA,2BAAAA,IAAC,OAAA,EAAM,WAAU,UAAA,CAAU,IAE3BA,2BAAAA,IAAC,MAAA,EAAK,WAAU,UAAA,CAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,cAK9BA,2BAAAA,IAAC,OAAA,EAAI,WAAW,mBAAmB,iBAAiB,KAAK,KAAK,WAAW,EAAE,IACzE,UAAAA,+BAAC,SAAA,EAAQ,WAAU,WAAU,GAC/B;AAAA,cAGAA,2BAAAA,IAAC,SAAI,WAAU,oBACZ,sBAAK,gCAAU,YAAS,UAAK,aAAL,mBAAe,MAAA,CAC1C;AAAA,cAGAA,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,SAAS,CAAC,MAAM;AACd,sBAAE,gBAAA;AACF,iCAAa,MAAM,IAAI;AAAA,kBACzB;AAAA,kBACA,WAAU;AAAA,kBAEV,UAAAA,2BAAAA,IAAC,MAAA,EAAK,WAAU,UAAA,CAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC5B,EAAA,CACF;AAAA,UAAA;AAAA,UAzCK,KAAK;AAAA,QAAA;AAAA,OA2Cb,GACH;AAAA,MAGC,MAAM,WAAW,KAChBA,2BAAAA,IAAC,OAAA,EAAI,WAAU,eACb,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,QAAAC,2BAAAA,IAACiB,cAAA,EAAM,WAAU,mBAAA,CAAmB;AAAA,QACpCjB,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAmB,UAAA,uBAAA,CAAoB;AAAA,MAAA,EAAA,CACtD,EAAA,CACF;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;ACxHO,MAAM,sBAAsB,CAAC,UAAsB;AACxD,QAAM,EAAE,QAAA,IAAY,SAAS,OAAO;AACpC,QAAM,eAAe,gBAAA;AACrB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAAA,IAAc;AAAA,IAAS;AAAA,MACzB,iBAAiB,MAAM,mBAAmB;AAAA,MAC1C,YAAY,MAAM;AAAA,MAClB,eAAe,MAAM;AAAA,IAAA;AAAA,IAEvB,MAAM;AAAA,EAAA;AAEN,QAAM,WAAW,OAAO,QAAgB;AACtC,UAAM,eAAe,MAAM;AACzB,UAAI;AACF,cAAM,IAAI,IAAI,IAAI,GAAG;AACrB,cAAM,QAAQ,EAAE,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AAClD,eAAO,mBAAmB,MAAM,MAAM,SAAS,CAAC,KAAK,GAAG;AAAA,MAC1D,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,GAAA;AAEA,UAAM,UAAU,MAAM,aAAa,QAAQ;AAAA,MACzC,MAAM;AAAA,MACN;AAAA,MACA,MAAM;AAAA,MACN,UAAU,EAAE,QAAQ,MAAA;AAAA,IAAM,CAC3B;AACD,YAAQ,OAAO;AAAA,EACjB;AAEA,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAAA;AAGN;ACxBO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,SACED,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,iBAAa;AAAA,IAG1CA,2BAAAA,IAAC,OAAA,EAAI,WAAU,iBACb,UAAAA,2BAAAA,IAAC,YAAS,MAAK,SAAQ,UAAU,SAAA,CAAU,EAAA,CAC7C;AAAA,IAcAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,cACX,WAAA,SAAS,CAAA,GAAI,IAAI,CAAC,SAClBD,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UAEC,eAAe,MAAM,aAAa,IAAI;AAAA,UACtC,WAAU;AAAA,UAEV,UAAA;AAAA,YAAAC,+BAAC,SAAI,KAAK,KAAK,KAAK,KAAI,IAAG,WAAU,sBAAqB;AAAA,YAG1DA,2BAAAA,IAAC,OAAA,EAAI,WAAU,iBACb,UAAAA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,CAAC,MAAM;AACd,oBAAE,gBAAA;AACF,+BAAa,MAAM,IAAI;AAAA,gBACzB;AAAA,gBACA,WAAU;AAAA,gBAEV,UAAAA,2BAAAA,IAAC,MAAA,EAAK,WAAU,UAAA,CAAU;AAAA,cAAA;AAAA,YAAA,EAC5B,CACF;AAAA,UAAA;AAAA,QAAA;AAAA,QAjBK,KAAK;AAAA,MAAA,CAmBb,GACH;AAAA,MAGC,MAAM,WAAW,KAChBA,2BAAAA,IAAC,OAAA,EAAI,WAAU,eACb,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,QAAAC,2BAAAA,IAACiB,cAAA,EAAM,WAAU,mBAAA,CAAmB;AAAA,QACpCjB,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAmB,UAAA,kBAAA,CAAe;AAAA,MAAA,EAAA,CACjD,EAAA,CACF;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;AC1FO,SAAS,oBAAoB,OAAmB;AACrD,QAAM,EAAE,QAAA,IAAY,SAAS,OAAO;AACpC,QAAM,eAAe,gBAAA;AACrB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAAA,IAAc;AAAA,IAAS;AAAA,MACzB,iBAAiB,MAAM,mBAAmB;AAAA,MAC1C,YAAY,MAAM;AAAA,MAClB,eAAe,MAAM;AAAA,IAAA;AAAA,IAEvB,MAAM;AAAA,EAAA;AAEN,QAAM,WAAW,OAAO,QAAgB;AACtC,UAAM,eAAe,MAAM;AACzB,UAAI;AACF,cAAM,IAAI,IAAI,IAAI,GAAG;AACrB,cAAM,QAAQ,EAAE,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AAClD,eAAO,mBAAmB,MAAM,MAAM,SAAS,CAAC,KAAK,GAAG;AAAA,MAC1D,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,GAAA;AAEA,UAAM,UAAU,MAAM,aAAa,QAAQ;AAAA,MACzC,MAAM;AAAA,MACN;AAAA,MACA,MAAM;AAAA,MACN,UAAU,EAAE,QAAQ,MAAA;AAAA,IAAM,CAC3B;AACD,YAAQ,OAAO;AAAA,EACjB;AAEA,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAAA;AAGN;AC3CO,MAAM,kBAAkB,MAA+C;AAC5E,QAAM,CAAC,cAAc,eAAe,IAAIC,MAAAA,SAAwB,IAAI;AACpE,QAAM,WAAWM,MAAAA,OAAgC,IAAI;AAGrDL,QAAAA,UAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,SAAS,SAAS;AACpB,iBAAS,QAAQ,MAAA;AACjB,iBAAS,UAAU;AAAA,MACrB;AAAA,IACF;AAAA,EACF,GAAG,CAAA,CAAE;AAEL,QAAM,eAAec,MAAAA,YAAY,MAAM;AACrC,QAAI,SAAS,SAAS;AACpB,eAAS,QAAQ,MAAA;AACjB,eAAS,UAAU;AAAA,IACrB;AACA,oBAAgB,IAAI;AAAA,EACtB,GAAG,CAAA,CAAE;AAEL,QAAM,kBAAkBA,MAAAA,YAAY,CAAC,MAAiB,iBAAmC;AAEvF,QAAI,iBAAiB,KAAK,IAAI;AAC5B,mBAAa,MAAA;AACb,mBAAA;AACA;AAAA,IACF;AAGA,iBAAA;AAGA,iBAAa,cAAc;AAC3B,iBAAa,KAAA;AACb,aAAS,UAAU;AACnB,oBAAgB,KAAK,EAAE;AAGvB,iBAAa,iBAAiB,SAAS,cAAc,EAAE,MAAM,MAAM;AAAA,EACrE,GAAG,CAAC,cAAc,YAAY,CAAC;AAE/B,SAAO;AAAA,IACL;AAAA,IACA,cAAc,SAAS;AAAA,IACvB;AAAA,IACA;AAAA,EAAA;AAEJ;AC5BO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,EAAE,cAAc,gBAAA,IAAoB,gBAAA;AAC1C,SACEjB,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,iBAAa;AAAA,IAG1CA,2BAAAA,IAAC,OAAA,EAAI,WAAU,sBACb,UAAAA,2BAAAA,IAAC,YAAS,MAAK,SAAQ,UAAU,SAAA,CAAU,EAAA,CAC7C;AAAA,IAeAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,cACX,WAAA,SAAS,CAAA,GAAI,IAAI,CAAC,SAClBD,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UAEC,eAAe,MAAM,aAAa,IAAI;AAAA,UACtC,WAAU;AAAA,UAEV,UAAA;AAAA,YAAAC,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,KAAK,KAAK;AAAA,gBACV,QAAQ,KAAK;AAAA,gBACb,WAAU;AAAA,gBACV,KAAK,CAAC,OAAO;AACX,sBAAI,IAAI;AACN,uBAAG,iBAAiB,SAAS,MAAM;AACjC,yBAAG,cAAc;AAAA,oBACnB,GAAG,EAAE,MAAM,MAAM;AAAA,kBACnB;AAAA,gBACF;AAAA,cAAA;AAAA,YAAA;AAAA,YASFD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBAEb,UAAA;AAAA,cAAAC,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,SAAS,CAAC,MAAM;;AACd,sBAAE,gBAAA;AACF,0BAAM,WAAU,aAAE,cAAc,kBAAhB,mBAA+B,kBAA/B,mBAA8C,cAAc;AAC5E,wBAAI,SAAS;AACX,sCAAgB,MAAM,OAAO;AAAA,oBAC/B;AAAA,kBACF;AAAA,kBACA,WAAU;AAAA,kBAET,UAAA,iBAAiB,KAAK,KACrBA,2BAAAA,IAAC,OAAA,EAAM,WAAU,UAAA,CAAU,IAE3BA,2BAAAA,IAAC,MAAA,EAAK,WAAU,UAAA,CAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,cAK9BA,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,SAAS,CAAC,MAAM;AACd,sBAAE,gBAAA;AACF,iCAAa,MAAM,IAAI;AAAA,kBACzB;AAAA,kBACA,WAAU;AAAA,kBAEV,UAAAA,2BAAAA,IAAC,MAAA,EAAK,WAAU,UAAA,CAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC5B,EAAA,CACF;AAAA,UAAA;AAAA,QAAA;AAAA,QApDK,KAAK;AAAA,MAAA,CAsDb,GACH;AAAA,MAGC,MAAM,WAAW,KAChBA,2BAAAA,IAAC,OAAA,EAAI,WAAU,eACb,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,QAAAC,2BAAAA,IAACiB,cAAA,EAAM,WAAU,mBAAA,CAAmB;AAAA,QACpCjB,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAmB,UAAA,kBAAA,CAAe;AAAA,MAAA,EAAA,CACjD,EAAA,CACF;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;ACjIO,SAAS,oBAAoB,OAAmB;AACrD,QAAM,EAAE,QAAA,IAAY,SAAS,OAAO;AACpC,QAAM,eAAe,gBAAA;AACrB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAAA,IAAc;AAAA,IAAS;AAAA,MACzB,iBAAiB,MAAM,mBAAmB;AAAA,MAC1C,YAAY,MAAM;AAAA,MAClB,eAAe,MAAM;AAAA,IAAA;AAAA,IAEvB,MAAM;AAAA,EAAA;AAEN,QAAM,WAAW,OAAO,QAAgB;AACtC,UAAM,eAAe,MAAM;AACzB,UAAI;AACF,cAAM,IAAI,IAAI,IAAI,GAAG;AACrB,cAAM,QAAQ,EAAE,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AAClD,eAAO,mBAAmB,MAAM,MAAM,SAAS,CAAC,KAAK,GAAG;AAAA,MAC1D,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,GAAA;AAEA,UAAM,UAAU,MAAM,aAAa,QAAQ;AAAA,MACzC,MAAM;AAAA,MACN;AAAA,MACA,MAAM;AAAA,MACN,UAAU,EAAE,QAAQ,MAAA;AAAA,IAAM,CAC3B;AACD,YAAQ,OAAO;AAAA,EACjB;AAEA,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,cAAc;AAAA,MACd,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAAA;AAGN;ACIO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,SACED,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,QAAI;AAAA,IAEjCA,2BAAAA,IAAC,OAAA,EAAI,WAAU,sBACb,UAAAA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAO;AAAA,QACP,aAAY;AAAA,QACZ,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,QAC9C,WAAU;AAAA,MAAA;AAAA,IAAA,GAEd;AAAA,IAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,aAAS;AAAA,MACvCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,YAAY,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,YACnD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZD,2BAAAA,KAAC,QAAA,EAAK,WAAU,gBAAgB,UAAA;AAAA,UAAA;AAAA,UAAS;AAAA,QAAA,EAAA,CAAE;AAAA,MAAA,EAAA,CAC7C;AAAA,IAAA,GACF;AAAA,IAGAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,QAAI;AAAA,MAClCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,gBAAgB,EAAE,OAAO,KAAK;AAAA,YAC/C,WAAU;AAAA,YAET,UAAA,MAAM,IAAI,CAAC,SACVA,2BAAAA,IAAC,YAAkB,OAAO,MACvB,UAAA,KAAA,GADU,IAEb,CACD;AAAA,UAAA;AAAA,QAAA;AAAA,QAEHA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAM,UAAU,CAAC,MAAM;AAAA,YAChC,WAAW,YAAY,SAAS,oBAAoB,EAAE;AAAA,YACvD,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGDA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAM,YAAY,CAAC,QAAQ;AAAA,YACpC,WAAW,YAAY,WAAW,oBAAoB,EAAE;AAAA,YACzD,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,UAAM;AAAA,MACpCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBAEb,UAAA;AAAA,QAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,eAAc,UAAA,cAAU;AAAA,UACzCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,YAAAC,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK;AAAA,gBAC5C,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEZA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK;AAAA,gBAC5C,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ,EAAA,CACF;AAAA,QAAA,GACF;AAAA,QAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,eAAc,UAAA,gBAAY;AAAA,UAC3CD,2BAAAA,KAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,YAAAC,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,gBAC9C,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEZA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,gBAC9C,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ,EAAA,CACF;AAAA,QAAA,GACF;AAAA,uCAGC,OAAA,EAAI,WAAU,oBACb,UAAAD,2BAAAA,KAAC,SAAA,EAAM,WAAU,kBACf,UAAA;AAAA,UAAAC,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS;AAAA,cACT,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,OAAO;AAAA,cAChD,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UACV;AAAA,QAAA,EAAA,CAEJ,EAAA,CACF;AAAA,QAGC,eACCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,eAAc,UAAA,gBAAY;AAAA,UAC3CD,2BAAAA,KAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,YAAAC,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,gBAC9C,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEZA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,gBAC9C,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ,EAAA,CACF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA,GACF;AAAA,IAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,gBAAY;AAAA,MAC1CD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,MAAM;AAAA,YACN,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,eAAe,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,YACtD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZA,2BAAAA,IAAC,QAAA,EAAK,WAAU,gBAAgB,UAAA,YAAA,CAAY;AAAA,MAAA,EAAA,CAC9C;AAAA,IAAA,GACF;AAAA,IAGAA,2BAAAA,IAAC,OAAA,EAAI,WAAU,sBACb,UAAAA,2BAAAA,IAAC,UAAA,EAAO,SAAS,oBAAoB,WAAU,sBAC5C,UAAA,UAAA,CACH,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AChPO,MAAM,qBAAqB;AAAA,EAChC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,WAAW;AAAA,EACX,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,WAAW;AAAA,EACX,cAAc,CAAC,GAAG,CAAC;AAAA,EACnB,YAAY;AAAA,EACZ,eAAe;AACjB;AA+BO,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,MAIyC;AACvC,QAAM,CAAC,aAAa,cAAc,IAAIC,MAAAA,SAAS,mBAAmB,IAAI;AACtE,QAAM,CAAC,UAAU,WAAW,IAAIA,MAAAA,SAAS,mBAAmB,QAAQ;AACpE,QAAM,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAS,mBAAmB,UAAU;AAC9E,QAAM,CAAC,QAAQ,SAAS,IAAIA,MAAAA,SAAS,mBAAmB,eAAe,GAAG;AAC1E,QAAM,CAAC,UAAU,WAAW,IAAIA,MAAAA,SAAS,mBAAmB,cAAc,QAAQ;AAClF,QAAM,CAAC,WAAW,YAAY,IAAIA,MAAAA,SAAS,mBAAmB,SAAS;AACvE,QAAM,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAS,mBAAmB,WAAW;AAC7E,QAAM,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAS,mBAAmB,WAAW;AAC7E,QAAM,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAS,mBAAmB,WAAW;AAC7E,QAAM,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAS,mBAAmB,WAAW;AAE7E,QAAM,QAAQ,OAAO,OAAOiB,gCAAoB;AAEhD,QAAM,qBAAqB,YAAY;AACrC,QAAI;AACJ,QAAI,2BAA2BC,SAAAA,aAAa;AAC1C,oBAAc;AACd,kBAAY,QAAQ,WAAW;AAC/B,kBAAY,YAAY,QAAQ;AAChC,kBAAY,cAAc,YAAY;AACtC,kBAAY,cAAc,SAAS,MAAM,GAAG;AAC5C,kBAAY,aAAa,WAAW,WAAW,QAAQ;AACvD,kBAAY,QAAQ,SAAS;AAC7B,kBAAY,eAAe,WAAW;AACtC,kBAAY,aAAa,WAAW;AACpC,kBAAY,aAAa,mBAAmB,SAAS;AACrD,UAAI,aAAa;AACf,oBAAY,SAAS;AAAA,UACnB,GAAG,YAAY,SAAA;AAAA,UACf;AAAA,UACA,cAAc,mBAAmB;AAAA,UACjC,YAAY,mBAAmB;AAAA,UAC/B,eAAe,mBAAmB;AAAA,QAAA,CACnC;AAAA,MACH,OAAO;AACL,oBAAY,SAAS;AAAA,UACnB,GAAG,YAAY,SAAA;AAAA,UACf,aAAa;AAAA,UACb,cAAc;AAAA,UACd,YAAY;AAAA,UACZ,eAAe;AAAA,QAAA,CAChB;AAAA,MACH;AACA,oBAAc,WAAW;AAAA,IAC3B,OAAO;AACL,oBAAc,IAAIA,SAAAA,YAAY,WAAW,EACtC,YAAY,QAAQ,EACpB,cAAc,YAAY,EAC1B,cAAc,SAAS,MAAM,GAAG,EAChC,aAAa,WAAW,WAAW,QAAQ,EAC3C,QAAQ,SAAS,EACjB,eAAe,WAAW,EAC1B,aAAa,WAAW,EACxB,aAAa,QAAQ;AAExB,UAAI,aAAa;AACf,oBAAY,SAAS;AAAA,UACnB,GAAG,YAAY,SAAA;AAAA,UACf;AAAA,UACA,cAAc,mBAAmB;AAAA,UACjC,YAAY,mBAAmB;AAAA,UAC/B,eAAe,mBAAmB;AAAA,QAAA,CACnC;AAAA,MACH;AACA,YAAM,WAAW,WAAW;AAAA,IAC9B;AAAA,EACF;AAEAjB,QAAAA,UAAU,MAAM;AACd,QAAI,2BAA2BiB,SAAAA,aAAa;AAC1C,qBAAe,gBAAgB,SAAS;AACxC,YAAM,YAAY,gBAAgB,SAAA;AAClC,sBAAgB,UAAU,cAAc,mBAAmB,UAAU;AACrE,kBAAY,UAAU,YAAY,mBAAmB,QAAQ;AAC7D,gBAAU,UAAU,eAAe,GAAG;AACtC,kBAAY,UAAU,cAAc,QAAQ;AAC5C,mBAAa,UAAU,QAAQ,mBAAmB,SAAS;AAC3D,qBAAe,UAAU,UAAU,mBAAmB,WAAW;AACjE,qBAAe,UAAU,aAAa,mBAAmB,WAAW;AACpE,YAAM,YAAY,UAAU,gBAAgB;AAC5C,qBAAe,SAAS;AACxB,UAAI,WAAW;AACb,uBAAe,UAAU,eAAe,mBAAmB,WAAW;AAAA,MACxE;AAAA,IACF,OAAO;AACL,qBAAe,mBAAmB,IAAI;AACtC,kBAAY,mBAAmB,QAAQ;AACvC,sBAAgB,mBAAmB,UAAU;AAC7C,gBAAU,mBAAmB,eAAe,GAAG;AAC/C,kBAAY,mBAAmB,cAAc,QAAQ;AACrD,mBAAa,mBAAmB,SAAS;AACzC,qBAAe,mBAAmB,WAAW;AAC7C,qBAAe,mBAAmB,WAAW;AAC7C,qBAAe,mBAAmB,WAAW;AAC7C,qBAAe,mBAAmB,WAAW;AAAA,IAC/C;AAAA,EACF,GAAG,CAAC,eAAe,CAAC;AAEpB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,2BAA2BA,uBAAc,kBAAiB;AAAA,IACrE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AC5KO,SAAS,mBAAmB,OAAgC;AACjE,QAAM,iBAAiB,aAAa,KAAK;AACzC,SAAOnB,+BAAC,WAAA,EAAW,GAAG,eAAA,CAAgB;AACxC;ACXA,MAAM,cAAc,CAAC;AAAA,EACnB;AAAA,EACA;AACF,MAGM;AACJ,SACED,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,IAAAC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,aAAY;AAAA,QACZ,OAAO;AAAA,QACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,QAC9C,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,IAEZA,2BAAAA,IAAC,QAAA,EAAO,WAAU,cAAA,CAAc;AAAA,EAAA,GAClC;AAEJ;ACwBO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,SACED,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,gBAAY;AAAA,IAGzCA,2BAAAA,IAAC,SAAI,WAAU,sBACb,yCAAC,aAAA,EAAY,aAA0B,gBAAgB,aAAA,CAAc,EAAA,CACvE;AAAA,IAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBAEZ,UAAA;AAAA,MAAA,aAAa,KACZA,gCAAC,OAAA,EAAI,WAAU,eAAc,UAAA;AAAA,QAAA;AAAA,QAClB,MAAM;AAAA,QAAO;AAAA,QAAK;AAAA,QAAW;AAAA,MAAA,GACxC;AAAA,MAID,WAAW,MAAM,WAAW,IAC3BC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eACb,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,QAAAC,2BAAAA,IAACoB,cAAA,EAAQ,WAAU,gCAAA,CAAgC;AAAA,QACnDpB,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAmB,UAAA,mBAAA,CAAgB;AAAA,MAAA,GAClD,GACF,IAEAA,+BAAC,OAAA,EAAI,WAAU,aACX,WAAA,SAAS,CAAA,GAAI,IAAI,CAAC,MAAY,UAC9BD,2BAAAA,KAAC,OAAA,EAAgB,WAAU,aACzB,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAM,gBAAgB,IAAI;AAAA,YACnC,WAAU;AAAA,YACV,yBAAyB,EAAE,QAAQ,KAAK,IAAA;AAAA,UAAI;AAAA,QAAA;AAAA,QAI9CD,2BAAAA,KAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,UAAAC,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,CAAC,MAAM;AACd,kBAAE,gBAAA;AACF,gCAAgB,IAAI;AAAA,cACtB;AAAA,cACA,WAAU;AAAA,cACV,OAAM;AAAA,cAEN,UAAAA,2BAAAA,IAAC,MAAA,EAAK,WAAU,UAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAE5BA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,CAAC,MAAM;AACd,kBAAE,gBAAA;AACF,mCAAmB,IAAI;AAAA,cACzB;AAAA,cACA,WAAU;AAAA,cACV,OAAM;AAAA,cAEN,UAAAA,2BAAAA,IAAC,UAAA,EAAS,WAAU,UAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QAChC,GACF;AAAA,QAGAA,2BAAAA,IAAC,OAAA,EAAI,WAAU,aAAa,eAAK,KAAA,CAAK;AAAA,MAAA,KAhC9B,KAiCV,CACD,GACH;AAAA,MAID,CAAC,WAAW,MAAM,WAAW,KAAK,eACjCA,2BAAAA,IAAC,OAAA,EAAI,WAAU,eACb,UAAAD,gCAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,QAAAC,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAmB,UAAA,kBAAc;AAAA,QAC9CA,2BAAAA,IAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,8BAAA,CAA2B;AAAA,MAAA,EAAA,CAChE,EAAA,CACF;AAAA,MAGD,CAAC,WAAW,cAAc,MAAM,SAAS,cACxCA,+BAAC,OAAA,EAAI,WAAU,sBACb,UAAAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS;AAAA,UACT,UAAU;AAAA,UACV,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA,EAED,CACF;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;AC3HA,MAAM,iBAAiB;AAEhB,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,MAIyC;AACvC,QAAM,CAAC,OAAO,QAAQ,IAAIC,MAAAA,SAAiB,CAAA,CAAE;AAC7C,QAAM,CAAC,SAAS,UAAU,IAAIA,MAAAA,SAAS,KAAK;AAC5C,QAAM,CAAC,MAAM,OAAO,IAAIA,MAAAA,SAAS,CAAC;AAClC,QAAM,CAAC,SAAS,UAAU,IAAIA,MAAAA,SAAS,IAAI;AAC3C,QAAM,CAAC,YAAY,aAAa,IAAIA,MAAAA,SAAS,CAAC;AAC9C,QAAM,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAS,EAAE;AACjD,QAAM,eAAeM,MAAAA,OAAO,EAAE;AAE9B,QAAM,aAAa,OAAO,OAAe,QAAQ,UAAU;AACzD,QAAI;AACF,iBAAW,IAAI;AACf,YAAM,UAAU,QAAQ,IAAI;AAC5B,YAAM,SAAS,UAAU,KAAK;AAC9B,YAAM,MAAM,2CAA2C,KAAK,UAAU,cAAc,WAAW,KAAK;AAEpG,YAAM,WAAW,MAAM,MAAM,GAAG;AAChC,YAAM,OAAO,MAAM,SAAS,KAAA;AAE5B,YAAM,WAAW,KAAK,SAAS,CAAA;AAC/B,YAAM,QAAQ,KAAK,SAAS;AAC5B,oBAAc,KAAK;AAEnB,YAAM,iBAAiB,MAAM,QAAQ;AAAA,QACnC,SAAS,IAAI,OAAO,SAAc;AAChC,gBAAM,SAAS,8BAA8B,IAAI;AAEjD,cAAI;AACF,kBAAM,cAAc,MAAM,MAAM,MAAM;AACtC,kBAAM,MAAM,MAAM,YAAY,KAAA;AAC9B,mBAAO,EAAE,MAAM,MAAM,IAAA;AAAA,UACvB,SAAS,GAAG;AACV,oBAAQ,MAAM,0BAA0B,IAAI,KAAK,CAAC;AAClD,mBAAO;AAAA,UACT;AAAA,QACF,CAAC;AAAA,MAAA;AAGH,YAAM,aAAa,eAAe,OAAO,CAAC,SAAS,SAAS,IAAI;AAEhE,UAAI,OAAO;AACT,iBAAS,UAAU;AAAA,MACrB,OAAO;AACL,iBAAS,CAAC,GAAG,OAAO,GAAG,UAAU,CAAC;AAAA,MACpC;AAEA,iBAAW,QAAQ,WAAW,SAAS,KAAK;AAC5C,UAAI,CAAC,OAAO;AACV,gBAAQ,UAAU,CAAC;AAAA,MACrB,OAAO;AACL,gBAAQ,CAAC;AAAA,MACX;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,yBAAyB,KAAK;AAAA,IAC9C,UAAA;AACE,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF;AAEAL,QAAAA,UAAU,MAAM;AACd,eAAW,SAAS,IAAI;AAAA,EAC1B,GAAG,CAAA,CAAE;AAEL,QAAM,eAAe,CAAC,UAAkB;AACtC,iBAAa,UAAU;AACvB,mBAAe,KAAK;AACpB,eAAW,OAAO,IAAI;AAAA,EACxB;AAEA,QAAM,kBAAkB,CAAC,SAAe;AACtC,UAAM,UAAU,IAAI,KAAK,CAAC,KAAK,GAAG,GAAG,EAAE,MAAM,iBAAiB;AAC9D,UAAM,MAAM,IAAI,gBAAgB,OAAO;AAEvC,QAAI;AACJ,QAAI,2BAA2BmB,SAAAA,aAAa;AAC1C,oBAAc;AACd,kBAAY,OAAO,GAAG;AACtB,kBAAY,QAAQ,KAAK,IAAI;AAC7B,qDAAgB;AAAA,IAClB,OAAO;AACL,oBAAc,IAAIA,SAAAA,YAAY,KAAK;AAAA,QACjC,OAAO;AAAA,QACP,QAAQ;AAAA,MAAA,CACT;AACD,kBAAY,QAAQ,KAAK,IAAI;AAC7B,+CAAa;AAAA,IACf;AAEA,QAAI,gBAAgB,GAAG;AAAA,EACzB;AAEA,QAAM,qBAAqB,CAAC,SAAe;AACzC,UAAM,OAAO,IAAI,KAAK,CAAC,KAAK,GAAG,GAAG,EAAE,MAAM,iBAAiB;AAC3D,UAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,UAAM,IAAI,SAAS,cAAc,GAAG;AACpC,MAAE,OAAO;AACT,MAAE,WAAW,GAAG,KAAK,IAAI;AACzB,aAAS,KAAK,YAAY,CAAC;AAC3B,MAAE,MAAA;AACF,aAAS,KAAK,YAAY,CAAC;AAC3B,QAAI,gBAAgB,GAAG;AAAA,EACzB;AAEA,QAAM,iBAAiB,MAAM;AAC3B,eAAW,aAAa,SAAS,KAAK;AAAA,EACxC;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;ACnJO,SAAS,mBAAmB,OAAmB;AACpD,QAAM,iBAAiB,aAAa;AAAA,IAClC,iBAAiB,MAAM,mBAAmB;AAAA,IAC1C,YAAY,MAAM;AAAA,IAClB,eAAe,MAAM;AAAA,EAAA,CACtB;AACD,SAAOrB,+BAAC,WAAA,EAAW,GAAG,eAAA,CAAgB;AACxC;AC+BO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,SACED,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,aAAS;AAAA,IAEtCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,iBAAa;AAAA,MAC3CD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,gBAAgB,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,YACvD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZD,2BAAAA,KAAC,QAAA,EAAK,WAAU,gBAAgB,UAAA;AAAA,UAAA;AAAA,UAAa;AAAA,QAAA,EAAA,CAAE;AAAA,MAAA,EAAA,CACjD;AAAA,IAAA,GACF;AAAA,IAGAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,cAAU;AAAA,MACxCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK;AAAA,YAC5C,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK;AAAA,YAC5C,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,WAAO;AAAA,MACrCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,WAAW,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,YAClD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZD,2BAAAA,KAAC,QAAA,EAAK,WAAU,gBAAgB,UAAA;AAAA,UAAA;AAAA,UAAQ;AAAA,QAAA,EAAA,CAAC;AAAA,MAAA,EAAA,CAC3C;AAAA,IAAA,GACF;AAAA,IAGAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,gBAAY;AAAA,MAC1CD,2BAAAA,KAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,YAC9C,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,YAC9C,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,cAAU;AAAA,MACxCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,aAAa,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,YACpD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZD,2BAAAA,KAAC,QAAA,EAAK,WAAU,gBAAgB,UAAA;AAAA,UAAA;AAAA,UAAU;AAAA,QAAA,EAAA,CAAE;AAAA,MAAA,EAAA,CAC9C;AAAA,IAAA,GACF;AAAA,IAGAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,sBACb,UAAAA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS;AAAA,QACT,WAAU;AAAA,QAET,UAAA;AAAA,MAAA;AAAA,IAAA,EACH,CACF;AAAA,EAAA,GACF;AAEJ;ACzJO,MAAM,qBAAqB;AAAA,EAChC,cAAc;AAAA,EACd,WAAW;AAAA,EACX,SAAS;AAAA,EACT,aAAa;AAAA,EACb,WAAW;AACb;AAoBO,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,MAIyC;AACvC,QAAM,CAAC,cAAc,eAAe,IAAIC,MAAAA,SAAS,mBAAmB,YAAY;AAChF,QAAM,CAAC,WAAW,YAAY,IAAIA,MAAAA,SAAS,mBAAmB,SAAS;AACvE,QAAM,CAAC,SAAS,UAAU,IAAIA,MAAAA,SAAS,mBAAmB,OAAO;AACjE,QAAM,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAS,mBAAmB,WAAW;AAC7E,QAAM,CAAC,WAAW,YAAY,IAAIA,MAAAA,SAAS,mBAAmB,SAAS;AAEvE,QAAM,qBAAqB,MAAM;AAC/B,QAAI;AACJ,QAAI,2BAA2BqB,SAAAA,aAAa;AAC1C,oBAAc;AACd,kBAAY,gBAAgB,YAAY;AACxC,kBAAY,WAAW,OAAO;AAC9B,kBAAY,eAAe,WAAW;AACtC,kBAAY,aAAa,SAAS;AAClC,qDAAgB;AAAA,IAClB,OAAO;AACL,oBAAc,IAAIA,SAAAA,YAAY,WAAW,EAAE,OAAO,KAAK,QAAQ,KAAK,EACjE,gBAAgB,YAAY,EAC5B,WAAW,OAAO,EAClB,eAAe,WAAW,EAC1B,aAAa,SAAS;AACzB,+CAAa;AAAA,IACf;AAAA,EACF;AAEApB,QAAAA,UAAU,MAAM;AACd,QAAI,2BAA2BoB,SAAAA,aAAa;AAC1C,sBAAgB,gBAAgB,qBAAqB,mBAAmB,YAAY;AACpF,mBAAa,gBAAgB,aAAa,mBAAmB,SAAS;AACtE,iBAAW,gBAAgB,gBAAgB,mBAAmB,OAAO;AACrE,qBAAe,gBAAgB,oBAAoB,mBAAmB,WAAW;AACjF,mBAAa,gBAAgB,kBAAkB,mBAAmB,SAAS;AAAA,IAC7E;AAAA,EACF,GAAG,CAAC,eAAe,CAAC;AAEpB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,2BAA2BA,uBAAc,kBAAiB;AAAA,IACrE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;ACnFO,SAAS,mBAAmB,OAAmB;AACpD,QAAM,iBAAiB,aAAa;AAAA,IAClC,iBAAiB,MAAM,mBAAmB;AAAA,IAC1C,YAAY,MAAM;AAAA,IAClB,eAAe,MAAM;AAAA,EAAA,CACtB;AACD,SAAOtB,+BAAC,WAAA,EAAW,GAAG,eAAA,CAAgB;AACxC;ACkCO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,SACED,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,UAAM;AAAA,IAEnCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,UAAM;AAAA,MACpCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,UAAU,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,YACjD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZD,2BAAAA,KAAC,QAAA,EAAK,WAAU,gBAAgB,UAAA;AAAA,UAAA;AAAA,UAAO;AAAA,QAAA,EAAA,CAAE;AAAA,MAAA,EAAA,CAC3C;AAAA,IAAA,GACF;AAAA,IAGAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,cAAU;AAAA,MACxCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK;AAAA,YAC5C,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK;AAAA,YAC5C,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,WAAO;AAAA,MACrCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,WAAW,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,YAClD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZD,2BAAAA,KAAC,QAAA,EAAK,WAAU,gBAAgB,UAAA;AAAA,UAAA;AAAA,UAAQ;AAAA,QAAA,EAAA,CAAC;AAAA,MAAA,EAAA,CAC3C;AAAA,IAAA,GACF;AAAA,IAGAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,gBAAY;AAAA,MAC1CD,2BAAAA,KAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,YAC9C,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,YAC9C,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,cAAU;AAAA,MACxCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,aAAa,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,YACpD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZD,2BAAAA,KAAC,QAAA,EAAK,WAAU,gBAAgB,UAAA;AAAA,UAAA;AAAA,UAAU;AAAA,QAAA,EAAA,CAAE;AAAA,MAAA,EAAA,CAC9C;AAAA,IAAA,GACF;AAAA,IAGAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,sBACb,UAAAA,2BAAAA,IAAC,UAAA,EAAO,SAAS,oBAAoB,WAAU,sBAC5C,UAAA,UAAA,CACH,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;ACzJO,MAAM,uBAAuB;AAAA,EAClC,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,SAAS;AAAA,EACT,aAAa;AAAA,EACb,WAAW;AACb;AAoBO,MAAM,iBAAiB,CAAC;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AACF,MAI6C;AAC3C,QAAM,CAAC,QAAQ,SAAS,IAAIC,MAAAA,SAAS,qBAAqB,MAAM;AAChE,QAAM,CAAC,WAAW,YAAY,IAAIA,MAAAA,SAAS,qBAAqB,SAAS;AACzE,QAAM,CAAC,SAAS,UAAU,IAAIA,MAAAA,SAAS,qBAAqB,OAAO;AACnE,QAAM,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAS,qBAAqB,WAAW;AAC/E,QAAM,CAAC,WAAW,YAAY,IAAIA,MAAAA,SAAS,qBAAqB,SAAS;AAEzE,QAAM,qBAAqB,MAAM;AAC/B,QAAI;AACJ,QAAI,2BAA2BsB,SAAAA,eAAe;AAC5C,sBAAgB;AAChB,oBAAc,UAAU,MAAM;AAC9B,oBAAc,QAAQ,SAAS;AAC/B,oBAAc,WAAW,OAAO;AAChC,oBAAc,eAAe,WAAW;AACxC,oBAAc,aAAa,SAAS;AACpC,qDAAgB;AAAA,IAClB,OAAO;AACL,sBAAgB,IAAIA,SAAAA,cAAc,WAAW,MAAM,EAChD,WAAW,OAAO,EAClB,eAAe,WAAW,EAC1B,aAAa,SAAS;AACzB,+CAAa;AAAA,IACf;AAAA,EACF;AAEArB,QAAAA,UAAU,MAAM;AACd,QAAI,2BAA2BqB,SAAAA,eAAe;AAC5C,gBAAU,gBAAgB,eAAe,qBAAqB,MAAM;AACpE,mBAAa,gBAAgB,aAAa,qBAAqB,SAAS;AACxE,iBAAW,gBAAgB,gBAAgB,qBAAqB,OAAO;AACvE,qBAAe,gBAAgB,oBAAoB,qBAAqB,WAAW;AACnF,mBAAa,gBAAgB,kBAAkB,qBAAqB,SAAS;AAAA,IAC/E;AAAA,EACF,GAAG,CAAC,eAAe,CAAC;AAEpB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,2BAA2BA,yBAAgB,kBAAiB;AAAA,IACvE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;ACnFO,SAAS,qBAAqB,OAAmB;AACtD,QAAM,mBAAmB,eAAe;AAAA,IACtC,iBAAiB,MAAM,mBAAmB;AAAA,IAC1C,YAAY,MAAM;AAAA,IAClB,eAAe,MAAM;AAAA,EAAA,CACtB;AACD,SAAOvB,+BAAC,aAAA,EAAa,GAAG,iBAAA,CAAkB;AAC5C;AC+BO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AAED,SACED,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,MAAA,EAAG,WAAU,eAAc,UAAA,aAAS;AAAA,IAGpC,UAAU,IAAI,CAAC,UAAU,MACxBD,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QAGV,UAAA;AAAA,UAAAC,+BAAC,OAAA,EACC,UAAAA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,aAAY;AAAA,cACZ,OAAO,SAAS;AAAA,cAChB,UAAU,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,UAAU,GAAG,EAAE,OAAO,MAAA,CAAO;AAAA,cACrE,WAAU;AAAA,YAAA;AAAA,UAAA,GAEd;AAAA,UAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,YAAAC,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAM,cAAc,CAAC;AAAA,gBAC9B,WAAU;AAAA,gBACV,OAAM;AAAA,gBAEN,UAAAA,2BAAAA,IAAC,UAAA,EAAS,WAAU,UAAA,CAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEhCA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAM,eAAe,CAAC;AAAA,gBAC/B,WAAU;AAAA,gBACV,OAAM;AAAA,gBAEN,UAAAA,2BAAAA,IAAC,QAAA,EAAO,WAAU,WAAU,OAAM,uBAAA,CAAsB;AAAA,cAAA;AAAA,YAAA;AAAA,UAC1D,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,MA9BK;AAAA,IAAA,CAgCR;AAAA,IAGDA,2BAAAA,IAAC,OAAA,EAAI,WAAU,iBACX,UAAAA,2BAAAA,IAAC,UAAA,EAAO,SAAS,aAAa,WAAU,sBAAqB,OAAM,gBAAe,iBAElF,EAAA,CACJ;AAAA,EAAA,GACF;AAEJ;ACvGO,MAAM,gBAAgB;AAAA,EACzB,CAACwB,SAAAA,cAAc,iBAAiB,GAAG;AAAA,IAC/B,MAAM;AAAA,MACF,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,IAAA;AAAA,IAEZ,QAAQ;AAAA,MACJ,MAAM;AAAA,MACN,WAAW;AAAA,MACX,SAAS;AAAA,IAAA;AAAA,IAEb,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,cAAc,CAAC,IAAI,CAAC;AAAA,IACpB,aAAa;AAAA,EAAA;AAAA,EAEjB,CAACA,SAAAA,cAAc,YAAY,GAAG;AAAA,IAC1B,MAAM;AAAA,MACF,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,IAAA;AAAA,IAEZ,QAAQ;AAAA,MACJ,MAAM;AAAA,MACN,WAAW;AAAA,MACX,SAAS;AAAA,IAAA;AAAA,IAEb,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,cAAc,CAAC,IAAI,CAAC;AAAA,IACpB,aAAa;AAAA,IACb,YAAY;AAAA,EAAA;AAAA,EAEhB,CAACA,SAAAA,cAAc,oBAAoB,GAAG;AAAA,IAClC,MAAM;AAAA,MACF,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,IAAA;AAAA,IAEZ,QAAQ;AAAA,MACJ,MAAM;AAAA,MACN,WAAW;AAAA,MACX,SAAS;AAAA,IAAA;AAAA,IAEb,WAAW;AAAA,IACX,cAAc,CAAC,IAAI,CAAC;AAAA,IACpB,aAAa;AAAA,IACb,YAAY;AAAA,EAAA;AAElB;AC3CK,MAAM,oBAAoB,MAAM;AACrC,QAAM,CAAC,WAAW,YAAY,IAAIvB,MAAAA,SAA0B,CAAA,CAAE;AAC9D,QAAM,iBAAiBM,MAAAA,OAAqB,IAAI;AAChD,QAAM,EAAE,OAAA,IAAWH,4BAAA;AAEnB,QAAM,iBAAiB,YAAY;AACjC,UAAM,uBAAuB,OAAO,kBAAA;AACpC,QAAI,sBAAsB;AACxB,qBAAe,UAAU;AACzB;AAAA,QACE,qBAAqB,YAAA,EAAc,IAAI,CAAC,aAAa;AAAA,UACnD,GAAG,QAAQ,SAAA;AAAA,UACX,GAAG,QAAQ,OAAA;AAAA,UACX,GAAI,QAA2B,QAAA;AAAA,QAAQ,EACvC;AAAA,MAAA;AAAA,IAEN;AAAA,EACF;AAEAF,QAAAA,UAAU,MAAM;AACd,mBAAA;AAAA,EACF,GAAG,CAAA,CAAE;AAEL,QAAM,sBAAsB,MAAM;;AAChC,QAAI,CAAC,eAAe,SAAS;AAC3B,qBAAe,UAAU,OAAO,SAAS,aAAa,SAAS;AAC/D,YAAM,QAA6B;AAAA,QACjC,UAAUsB,SAAAA,cAAc;AAAA,QACxB,GAAG,cAAcA,SAAAA,cAAc,iBAAiB;AAAA,QAChD,GAAG;AAAA,QACH,GAAG;AAAA,QACH,YAAY;AAAA,MAAA;AAEd,2BAAe,YAAf,mBAAwB,SAAS;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,cAAc,MAAM;AACxB,UAAM,cAA6B,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,eAAA;AACpD,QAAI,UAAU,SAAS,GAAG;AACxB,kBAAY,IAAI,UAAU,UAAU,SAAS,CAAC,EAAE;AAAA,IAClD;AACA,gBAAY,IAAI,YAAY,IAAI;AAChC,iBAAa,CAAC,GAAG,WAAW,WAAW,CAAC;AACxC,wBAAA;AACA,UAAM,iBAAiB,IAAIC,SAAAA;AAAAA,MACzB,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAEd,WAAO,kBAAkB,eAAe,SAAkB,cAAc;AAAA,EAC1E;AAEA,QAAM,gBAAgB,OAAO,UAAkB;AAC7C,QAAI,eAAe,SAAS;AAC1B,YAAM,UAAU,eAAe,QAAQ,YAAA,EACrC,KACF;AACA,YAAM,cAAc,MAAM,OAAO;AAAA,QAC/B;AAAA,QACA,QAAQ,SAAA,IAAa,QAAQ,gBAAgB;AAAA,MAAA;AAE/C,UAAI,YAAY,SAAS;AACvB,uBAAA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,UAAkB;AACxC,iBAAa,UAAU,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,CAAC;AACpD,QAAI,eAAe,SAAS;AAC1B,aAAO,cAAc,eAAe,QAAQ,YAAA,EAAc,KAAK,CAAC;AAAA,IAClE;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,OAAe,aAA4B;AACjE,iBAAa,UAAU,IAAI,CAAC,KAAK,MAAO,MAAM,QAAQ,WAAW,GAAI,CAAC;AACtE,QAAI,eAAe,SAAS;AAC1B,YAAM,UAAU,eAAe,QAAQ,YAAA,EACrC,KACF;AACA,cAAQ,QAAQ,SAAS,CAAC;AAC1B,aAAO,cAAc,OAAO;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;ACpGO,SAAS,0BAA0B;AACxC,QAAM,sBAAsB,kBAAA;AAC5B,SAAOzB,+BAAC,gBAAA,EAAgB,GAAG,oBAAA,CAAqB;AAClD;ACwCA,MAAM,wBAAwB,CAAC;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAsD;AACpD,QAAM,gBAAgB,OAAO,YAA0B;AACrD,UAAM,WAAW,OAAO;AAAA,EAC1B;AAGA,QAAM,gBAAgB,MAAM;AAC1B,YAAQ,cAAA;AAAA,MACN,KAAK;AACH,eACEA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,YAAY;AAAA,YACZ;AAAA,UAAA;AAAA,QAAA;AAAA,MAGN,KAAK;AACH,eACEA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,YAAY;AAAA,YACZ;AAAA,UAAA;AAAA,QAAA;AAAA,MAGN,KAAK;AACH,eACEA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,YAAY;AAAA,YACZ;AAAA,UAAA;AAAA,QAAA;AAAA,MAGN,KAAK;AACH,eACEA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA,YAAY;AAAA,YACZ;AAAA,UAAA;AAAA,QAAA;AAAA,MAGN,KAAK;AACH,eACEA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,YAAY;AAAA,YACZ;AAAA,UAAA;AAAA,QAAA;AAAA,MAGN,KAAK;AACH,eACEA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,YAAY;AAAA,YACZ;AAAA,UAAA;AAAA,QAAA;AAAA,MAGN,KAAK;AACH,eACEA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,YAAY;AAAA,YACZ;AAAA,UAAA;AAAA,QAAA;AAAA,MAGN,KAAK;AACH,8CAAQ,yBAAA,EAAwB;AAAA,MAClC;AACE,eACEA,2BAAAA,IAAC,OAAA,EAAI,WAAU,mBACb,UAAAA,2BAAAA,IAAC,OAAA,EAAI,WAAU,eACb,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,UAAAC,2BAAAA,IAACiB,cAAA,EAAM,WAAU,mBAAA,CAAmB;AAAA,UACpCjB,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAmB,UAAA,iCAAA,CAA8B;AAAA,QAAA,EAAA,CAChE,GACF,GACF;AAAA,IAAA;AAAA,EAGR;AAEA,SAAO,cAAA;AACT;AC3FA,MAAM,sCAAiD,IAAI;AAAA,EACzD;AAAA,IACE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF;AAAA,IACE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAEJ,CAAC;AAED,MAAM,UAAU,CAAC,aAAqB;AACpC,UAAQ,UAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO0B;AAAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EAAA;AAEb;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,oBAAoBC,MAAAA,QAAQ,MAAM;AACtC,UAAM,WAA2B,CAAA;AACjC,QAAI,2BAA2BR,SAAAA,aAAa;AAC1C,eAAS,KAAK,gBAAgB,IAAI,eAAe,CAAE;AACnD,eAAS,KAAK,gBAAgB,IAAI,YAAY,CAAE;AAChD,eAAS,KAAK,gBAAgB,IAAI,cAAc,CAAE;AAAA,IACpD,WAAW,2BAA2BL,uBAAc;AAClD,eAAS,KAAK,gBAAgB,IAAI,eAAe,CAAE;AACnD,eAAS,KAAK,gBAAgB,IAAI,YAAY,CAAE;AAChD,eAAS,KAAK,gBAAgB,IAAI,eAAe,CAAE;AAAA,IACrD,WAAW,2BAA2BF,uBAAc;AAClD,eAAS,KAAK,gBAAgB,IAAI,eAAe,CAAE;AACnD,eAAS,KAAK,gBAAgB,IAAI,YAAY,CAAE;AAChD,eAAS,KAAK,gBAAgB,IAAI,eAAe,CAAE;AACnD,eAAS,KAAK,gBAAgB,IAAI,gBAAgB,CAAE;AACpD,eAAS,KAAK,gBAAgB,IAAI,oBAAoB,CAAE;AAAA,IAC1D,WAAW,2BAA2BC,uBAAc;AAClD,eAAS,KAAK,gBAAgB,IAAI,eAAe,CAAE;AACnD,eAAS,KAAK,gBAAgB,IAAI,gBAAgB,CAAE;AAAA,IACtD,WAAW,2BAA2BU,wBAAe;AACnD,eAAS,KAAK,gBAAgB,IAAI,eAAe,CAAE;AACnD,eAAS,KAAK,gBAAgB,IAAI,YAAY,CAAE;AAAA,IAClD,WAAW,2BAA2BD,sBAAa;AACjD,eAAS,KAAK,gBAAgB,IAAI,eAAe,CAAE;AACnD,eAAS,KAAK,gBAAgB,IAAI,YAAY,CAAE;AAAA,IAClD,WAAW,2BAA2BD,sBAAa;AACjD,eAAS,KAAK,gBAAgB,IAAI,eAAe,CAAE;AACnD,eAAS,KAAK,gBAAgB,IAAI,YAAY,CAAE;AAAA,IAClD,WAAW,2BAA2BI,yBAAgB;AACpD,eAAS,KAAK,gBAAgB,IAAI,eAAe,CAAE;AACnD,eAAS,KAAK,gBAAgB,IAAI,YAAY,CAAE;AAChD,eAAS,KAAK,gBAAgB,IAAI,gBAAgB,CAAE;AAAA,IACtD;AACA,WAAO;AAAA,EACT,GAAG,CAAC,eAAe,CAAC;AAEpBvB,QAAAA,UAAU,MAAM;AACd,QAAI,uDAAmB,QAAQ;AAC7B,UACE,kBAAkB,IAAI,CAAC,YAAY,QAAQ,EAAE,EAAE,QAAQ,YAAY,MACnE,IACA;AACA,wBAAgB,kBAAkB,CAAC,EAAE,EAAE;AAAA,MACzC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,iBAAiB,CAAC;AAEtB,wCACG,OAAA,EAAI,WAAU,WAEZ,UAAA,kBAAkB,IAAI,CAAC,SAAS;AAC/B,UAAMJ,QAAO,QAAQ,KAAK,IAAI;AAC9B,UAAM,aAAa,iBAAiB,KAAK;AACzC,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QAEC,SAAS,MAAM,gBAAgB,KAAK,EAAE;AAAA,QACtC,WAAW,eAAe,aAAa,WAAW,EAAE;AAAA,QACpD,OAAO,GAAG,KAAK,IAAI,GAAG,KAAK,WAAW,KAAK,KAAK,QAAQ,MAAM,EAAE;AAAA,QAEhE,UAAA;AAAA,UAAAC,2BAAAA,IAACF,OAAA,EAAK,WAAU,UAAA,CAAU;AAAA,UAC1BE,2BAAAA,IAAC,QAAA,EAAK,WAAU,uBAAuB,eAAK,KAAA,CAAK;AAAA,QAAA;AAAA,MAAA;AAAA,MAN5C,KAAK;AAAA,IAAA;AAAA,EAShB,CAAC,EAAA,CACH;AAEJ;ACrNO,SAAS,aAAa,EAAE,iBAAiB,iBAAuC;AACrF,QAAM,gBAAe,mDAAiB,eAAc,CAAA;AACpD,QAAM,EAAC,GAAG,GAAG,SAAS,aAAY;AAElC,QAAM,sBAAsB,CAAC,UAA+B;AAC1D,QAAG,iBAAiB;AAClB,qDAAgB,mDAAiB,SAAS,EAAC,GAAG,cAAa,GAAG,MAAA;AAAA,IAChE;AAAA,EACF;AACA,SACED,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,kBAAc;AAAA,IAC3CD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,YAAQ;AAAA,MACtCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,QAAAA,gCAAC,OAAA,EACC,UAAA;AAAA,UAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,eAAc,UAAA,KAAC;AAAA,UAChCA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAO,KAAK;AAAA,cACZ,UAAU,CAAC,MAAM,oBAAoB,EAAE,GAAG,OAAO,EAAE,OAAO,KAAK,GAAE;AAAA,cACjE,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ,GACF;AAAA,wCACC,OAAA,EACC,UAAA;AAAA,UAAAA,2BAAAA,IAAC,SAAA,EAAM,WAAU,eAAc,UAAA,KAAC;AAAA,UAChCA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAO,KAAK;AAAA,cACZ,UAAU,CAAC,MAAM,oBAAoB,EAAE,GAAG,OAAO,EAAE,OAAO,KAAK,GAAE;AAAA,cACjE,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,WAAO;AAAA,MACrCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,QAAQ,WAAW,KAAK;AAAA,YACxB,UAAU,CAAC,MAAM,oBAAoB,EAAE,SAAS,OAAO,EAAE,OAAO,KAAK,IAAI,IAAA,CAAI;AAAA,YAC7E,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZD,2BAAAA,KAAC,QAAA,EAAK,WAAU,gBAAgB,UAAA;AAAA,UAAA,KAAK,OAAO,WAAW,KAAK,GAAG;AAAA,UAAE;AAAA,QAAA,EAAA,CAAC;AAAA,MAAA,EAAA,CACpE;AAAA,IAAA,GACF;AAAA,IAGAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,YAAQ;AAAA,MACtCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,OAAO,YAAY;AAAA,YACnB,UAAU,CAAC,MAAM,oBAAoB,EAAE,UAAU,OAAO,EAAE,OAAO,KAAK,GAAE;AAAA,YACxE,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZD,2BAAAA,KAAC,QAAA,EAAK,WAAU,gBAAgB,UAAA;AAAA,UAAA,YAAY;AAAA,UAAE;AAAA,QAAA,EAAA,CAAC;AAAA,MAAA,EAAA,CACjD;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;ACnEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AACF,GAAyB;AACvB,MAAI,EAAE,2BAA2BoB,sBAAc,QAAO;AAEtD,QAAM,gBAAgB,gBAAgB,cAAA;AAEtC,QAAM,qBAAqB,CAAC,UAKtB;AACJ,QAAI,CAAC,mBAAmB,EAAE,2BAA2BA,SAAAA,aAAc;AAEnE,QAAI,SAAS;AAGb,QAAI,MAAM,SAAS,IAAI;AACrB,sBAAgB,cAAc,MAAS;AACvC,qDAAgB;AAChB;AAAA,IACF;AAGA,QAAI,CAAC,UAAW,MAAM,QAAQ,MAAM,SAAS,OAAO,WAAY;AAC9D,eAAS,IAAIS,SAAAA;AAAAA,QACX,MAAM,SAAQ,+CAAe,cAAaC,YAAAA,aAAa,CAAC,EAAE;AAAA,MAAA;AAG5D,aAAO,SAAS,CAAC;AACjB,aAAO,YAAY,CAAC;AACpB,aAAO,cAAc,GAAG;AAAA,IAC1B;AAGA,QAAI,MAAM,UAAU,OAAW,QAAO,SAAS,MAAM,KAAK;AAC1D,QAAI,MAAM,aAAa,OAAW,QAAO,YAAY,MAAM,QAAQ;AACnE,QAAI,MAAM,eAAe,OAAW,QAAO,cAAc,MAAM,UAAU;AAGzE,oBAAgB,cAAc,MAAM;AACpC,mDAAgB;AAAA,EAClB;AAEA,SACE9B,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,gBAAY;AAAA,IAEzCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,oBAAgB;AAAA,MAC9CD,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,QAAO,+CAAe,cAAa;AAAA,UACnC,UAAU,CAAC,MAAM,mBAAmB,EAAE,MAAM,EAAE,OAAO,OAAO;AAAA,UAC5D,WAAU;AAAA,UAEV,UAAA;AAAA,YAAAC,2BAAAA,IAAC,UAAA,EAAO,OAAM,IAAG,UAAA,aAAS;AAAA,YACzB6B,YAAAA,aAAa,IAAI,CAAC,0CAChB,UAAA,EAAyB,OAAO,OAAO,MACrC,UAAA,OAAO,KAAK,OAAO,CAAC,EAAE,YAAA,IAAgB,OAAO,KAAK,MAAM,CAAC,KAD/C,OAAO,IAEpB,CACD;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACH,GACF;AAAA,IAGC,iBACC9B,2BAAAA,KAAA+B,qBAAA,EAEE,UAAA;AAAA,MAAA/B,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,QAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,mBAAe;AAAA,QAC7CA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,MAAK;AAAA,YACL,OAAO,cAAc,SAAA,KAAc;AAAA,YACnC,UAAU,CAAC,MACT,mBAAmB,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK,GAAG;AAAA,YAEtD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ,GACF;AAAA,MAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,QAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,sBAAkB;AAAA,QAChDA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,MAAK;AAAA,YACL,OAAO,cAAc,YAAA,KAAiB;AAAA,YACtC,UAAU,CAAC,MACT,mBAAmB,EAAE,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG;AAAA,YAEzD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ,GACF;AAAA,MAGAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,QAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,yBAAqB;AAAA,QACnDA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,MAAK;AAAA,YACL,OAAO,cAAc,cAAA,KAAmB;AAAA,YACxC,UAAU,CAAC,MACT,mBAAmB,EAAE,YAAY,OAAO,EAAE,OAAO,KAAK,GAAG;AAAA,YAE3D,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;ACxHO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AACF,GAAyB;AACvB,MAAI,EAAE,2BAA2BM,uBAAe,QAAO;AAEvD,QAAM,mBAAmB,mDAAiB;AAE1C,QAAM,wBAAwB,CAAC,UAQzB;;AACJ,QAAI,CAAC,gBAAiB;AAEtB,QAAI,YAAY;AAGhB,QAAI,MAAM,SAAS,IAAI;AACrB,sBAAgB,aAAa,MAAS;AACtC,qDAAgB;AAChB;AAAA,IACF;AAGA,UAAM,eAAeyB,YAAAA,WAAW;AAAA,MAC9B,CAAC,MAAM,EAAE,UAAU,MAAM,SAAQ,qDAAkB;AAAA,IAAQ;AAE7D,QAAI,CAAC,aAAc;AAGnB,QAAI,CAAC,aAAc,MAAM,QAAQ,MAAM,SAAS,UAAU,WAAY;AACpE,kBAAY,IAAIC,SAAAA;AAAAA,QACd,MAAM,SAAQ,qDAAkB,cAAaD,YAAAA,WAAW,CAAC,EAAE;AAAA,MAAA;AAG7D,gBAAU,YAAY,aAAa,YAAY,CAAC;AAChD,gBAAU,YAAY,aAAa,YAAY,CAAC;AAChD,gBAAU,aAAa,aAAa,aAAa,CAAC;AAClD,gBAAU,WAAW,aAAa,WAAW,OAAO;AACpD,UAAI,aAAa,KAAM,WAAU,QAAQ,aAAa,IAAI;AAC1D,UAAI,aAAa;AACf,kBAAU,aAAa,aAAa,SAAS;AAAA,IACjD;AAGA,QAAI,MAAM,aAAa,QAAW;AAChC,YAAM,CAAC,KAAK,GAAG,MAAI,kBAAa,YAAb,mBAAsB,aAAY,CAAC,KAAK,CAAC;AAC5D,gBAAU,YAAY,KAAK,IAAI,KAAK,IAAI,MAAM,UAAU,GAAG,GAAG,GAAG,CAAC;AAAA,IACpE;AACA,QAAI,MAAM,aAAa,QAAW;AAChC,YAAM,CAAC,KAAK,GAAG,MAAI,kBAAa,YAAb,mBAAsB,aAAY,CAAC,KAAK,CAAC;AAC5D,gBAAU,YAAY,KAAK,IAAI,KAAK,IAAI,MAAM,UAAU,GAAG,GAAG,GAAG,CAAC;AAAA,IACpE;AACA,QAAI,MAAM,cAAc,QAAW;AACjC,YAAM,CAAC,KAAK,GAAG,MAAI,kBAAa,YAAb,mBAAsB,cAAa,CAAC,KAAK,CAAC;AAC7D,gBAAU,aAAa,KAAK,IAAI,KAAK,IAAI,MAAM,WAAW,GAAG,GAAG,GAAG,CAAC;AAAA,IACtE;AACA,QACE,MAAM,aACN,wBAAa,YAAb,mBAAsB,YAAtB,mBAA+B,SAAS,MAAM,WAC9C;AACA,gBAAU,WAAW,MAAM,OAAO;AAAA,IACpC;AACA,QAAI,MAAM,UAAQ,wBAAa,YAAb,mBAAsB,SAAtB,mBAA4B,SAAS,MAAM,QAAO;AAClE,gBAAU,QAAQ,MAAM,IAAI;AAAA,IAC9B;AACA,QACE,MAAM,eACN,wBAAa,YAAb,mBAAsB,cAAtB,mBAAiC,SAAS,MAAM,aAChD;AACA,gBAAU,aAAa,MAAM,SAAS;AAAA,IACxC;AAGA,oBAAgB,aAAa,SAAS;AACtC,mDAAgB;AAAA,EAClB;AAEA,SACEhC,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,cAAU;AAAA,IAEvCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,QAAI;AAAA,MAClCD,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,QAAO,qDAAkB,cAAa;AAAA,UACtC,UAAU,CAAC,MAAM,sBAAsB,EAAE,MAAM,EAAE,OAAO,OAAO;AAAA,UAC/D,WAAU;AAAA,UAEV,UAAA;AAAA,YAAAC,2BAAAA,IAAC,UAAA,EAAO,OAAM,IAAG,UAAA,gBAAY;AAAA,YAC5B+B,YAAAA,WAAW,IAAI,CAAC,6CACd,UAAA,EAA4B,OAAO,UAAU,MAC3C,UAAA,UAAU,KAAK,OAAO,CAAC,EAAE,YAAA,IAAgB,UAAU,KAAK,MAAM,CAAC,KADrD,UAAU,IAEvB,CACD;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACH,GACF;AAAA,IAGC,0EAGO,WAAA,MAAM;;AACN,YAAM,eAAeA,YAAAA,WAAW;AAAA,QAC9B,CAAC,MAAM,EAAE,SAAS,iBAAiB,QAAA;AAAA,MAAQ;AAE7C,UAAI,CAAC,gBAAgB,CAAC,aAAa,QAAS,QAAO;AAEnD,aACEhC,2BAAAA,KAAA+B,qBAAA,EAEG,UAAA;AAAA,UAAA,kBAAa,YAAb,mBAAsB,YACrB/B,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,mBAAe;AAAA,UAC7CA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO,iBAAiB,WAAA;AAAA,cACxB,UAAU,CAAC,MACT,sBAAsB;AAAA,gBACpB,SAAS,EAAE,OAAO;AAAA,cAAA,CAInB;AAAA,cAEH,WAAU;AAAA,cAET,WAAA,kBAAa,YAAb,mBAAsB,QAAQ,IAAI,CAAC,WAClCA,2BAAAA,IAAC,YAAoB,OAAO,QACzB,iBAAO,OAAO,CAAC,EAAE,YAAA,IAAgB,OAAO,MAAM,CAAC,EAAA,GADrC,MAEb;AAAA,YACD;AAAA,UAAA;AAAA,QACH,GACF;AAAA,UAID,kBAAa,YAAb,mBAAsB,cACrBD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,aAAS;AAAA,UACvCA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO,iBAAiB,aAAA;AAAA,cACxB,UAAU,CAAC,MACT,sBAAsB;AAAA,gBACpB,WAAW,EAAE,OAAO;AAAA,cAAA,CAMrB;AAAA,cAEH,WAAU;AAAA,cAET,WAAA,kBAAa,YAAb,mBAAsB,UAAU,IAAI,CAAC,WACpCA,2BAAAA,IAAC,YAAoB,OAAO,QACzB,iBAAO,OAAO,CAAC,EAAE,YAAA,IAAgB,OAAO,MAAM,CAAC,EAAA,GADrC,MAEb;AAAA,YACD;AAAA,UAAA;AAAA,QACH,GACF;AAAA,UAID,kBAAa,YAAb,mBAAsB,SACrBD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,QAAI;AAAA,UAClCA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO,iBAAiB,QAAA;AAAA,cACxB,UAAU,CAAC,MACT,sBAAsB;AAAA,gBACpB,MAAM,EAAE,OAAO;AAAA,cAAA,CAChB;AAAA,cAEH,WAAU;AAAA,cAET,WAAA,kBAAa,YAAb,mBAAsB,KAAK,IAAI,CAAC,WAC/BA,2BAAAA,IAAC,YAAoB,OAAO,QACzB,iBAAO,OAAO,CAAC,EAAE,YAAA,IAAgB,OAAO,MAAM,CAAC,EAAA,GADrC,MAEb;AAAA,YACD;AAAA,UAAA;AAAA,QACH,GACF;AAAA,UAID,kBAAa,YAAb,mBAAsB,aACrBD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,sBAAkB;AAAA,UAChDD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,YAAAC,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK,kBAAa,YAAb,mBAAsB,SAAS;AAAA,gBACpC,MAAK,kBAAa,YAAb,mBAAsB,SAAS;AAAA,gBACpC,MAAK;AAAA,gBACL,OAAO,iBAAiB,YAAA;AAAA,gBACxB,UAAU,CAAC,MACT,sBAAsB;AAAA,kBACpB,UAAU,OAAO,EAAE,OAAO,KAAK;AAAA,gBAAA,CAChC;AAAA,gBAEH,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,2CAEX,QAAA,EAAK,WAAU,gBAAgB,UAAA,iBAAiB,cAAY,CAAE;AAAA,UAAA,EAAA,CACjE;AAAA,QAAA,GACF;AAAA,UAID,kBAAa,YAAb,mBAAsB,aACrBD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,sBAAkB;AAAA,UAChDD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,YAAAC,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK,kBAAa,YAAb,mBAAsB,SAAS;AAAA,gBACpC,MAAK,kBAAa,YAAb,mBAAsB,SAAS;AAAA,gBACpC,MAAK;AAAA,gBACL,OAAO,iBAAiB,YAAA;AAAA,gBACxB,UAAU,CAAC,MACT,sBAAsB;AAAA,kBACpB,UAAU,OAAO,EAAE,OAAO,KAAK;AAAA,gBAAA,CAChC;AAAA,gBAEH,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,2CAEX,QAAA,EAAK,WAAU,gBAAgB,UAAA,iBAAiB,cAAY,CAAE;AAAA,UAAA,EAAA,CACjE;AAAA,QAAA,GACF;AAAA,UAID,kBAAa,YAAb,mBAAsB,cACrBD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,aAAS;AAAA,UACvCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,YAAAC,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK,kBAAa,YAAb,mBAAsB,UAAU;AAAA,gBACrC,MAAK,kBAAa,YAAb,mBAAsB,UAAU;AAAA,gBACrC,MAAK;AAAA,gBACL,OAAO,iBAAiB,aAAA;AAAA,gBACxB,UAAU,CAAC,MACT,sBAAsB;AAAA,kBACpB,WAAW,OAAO,EAAE,OAAO,KAAK;AAAA,gBAAA,CACjC;AAAA,gBAEH,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,2CAEX,QAAA,EAAK,WAAU,gBAAgB,UAAA,iBAAiB,eAAa,CAAE;AAAA,UAAA,EAAA,CAClE;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,GAEJ;AAAA,IAEJ,KAAG,CACP;AAAA,EAAA,GAEJ;AAEJ;AC3QO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,gBAAe,mDAAiB,eAAc,CAAA;AACpD,QAAM,EAAE,WAAW;AAEnB,QAAM,sBAAsB,CAAC,UAA+B;AAC1D,QAAI,iBAAiB;AACnB,qDAAgB,mDAAiB,SAAS,EAAE,GAAG,cAAc,GAAG,MAAA;AAAA,IAClE;AAAA,EACF;AACA,SACED,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,uBAAmB;AAAA,IAEhDD,2BAAAA,KAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAM,WAAU,cAAa,UAAA,UAAM;AAAA,MACpCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,MAAM;AAAA,YACN,OAAO,UAAU;AAAA,YACjB,UAAU,CAAC,MACT,oBAAoB,EAAE,QAAQ,OAAO,EAAE,OAAO,KAAK,GAAG;AAAA,YAExD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZA,2BAAAA,IAAC,QAAA,EAAK,WAAU,gBAAgB,oBAAU,EAAA,CAAE;AAAA,MAAA,EAAA,CAC9C;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AC4LA,MAAM,WAAW,OAAO,QAAQ;AAC9B,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,YAAY,0BAA0B,KAAK,GAAG;AACpD,MAAI,CAAC,UAAW,QAAO;AACvB,MAAI;AACF,UAAM,cAAc,MAAM,oBAAoB,GAAG;AACjD,QAAI,YAAY,aAAa,KAAK,YAAY,WAAW,GAAG;AAC1D,aAAO;AAAA,IACT;AACA,QAAI,cAAc,WAAW,GAAG;AAC9B,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO;AAAA,EACT;AACF;AAUA,MAAM,sBAAsB,OAAO,QAAQ;AACzC,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,2BAA2B,SAAS,MAAM,EAAE;AAC9E,QAAM,cAAc,MAAM,SAAS,YAAW;AAC9C,SAAO,gBAAgB,WAAW;AACpC;AACA,MAAM,kBAAkB,OAAO,gBAAgB;AAC7C,QAAM,mBAAmB,OAAO,gBAAgB,OAAO;AACvD,MAAI,CAAC,iBAAkB,OAAM,IAAI,MAAM,6BAA6B;AACpE,QAAM,eAAe,IAAI,iBAAgB;AACzC,MAAI;AACF,WAAO,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC5C,mBAAa;AAAA,QACX,YAAY,MAAM,CAAC;AAAA,QACnB,CAAC,QAAQ,QAAQ,GAAG;AAAA,QACpB,CAAC,QAAQ,OAAO,OAAO,IAAI,MAAM,oEAAoE,CAAC;AAAA,MAC9G;AAAA,IACI,CAAC;AAAA,EACH,UAAC;AACC,iBAAa,MAAK;AAAA,EACpB;AACF;AACA,MAAM,gBAAgB,CAAC,QAAQ,YAAY,SAAS;AAClD,WAAS,UAAU,GAAG,UAAU,OAAO,kBAAkB,WAAW;AAClE,UAAM,cAAc,OAAO,eAAe,OAAO;AACjD,aAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK,KAAK;AAChD,UAAI,KAAK,IAAI,YAAY,CAAC,CAAC,IAAI,WAAW;AACxC,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAgQA,MAAM,WAAW,CAAC,WAAW;AAC3B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI;AACF,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,OAAO;AACb,YAAM,SAAS;AACf,YAAM,MAAM,UAAU;AACtB,eAAS,KAAK,YAAY,KAAK;AAC/B,YAAM,UAAU,MAAM;AACpB,cAAM,QAAQ;AACd,iBAAS,KAAK,YAAY,KAAK;AAAA,MACjC;AACA,YAAM,WAAW,MAAM;AACrB,cAAM,OAAO,MAAM,SAAS,MAAM,MAAM,CAAC;AACzC,gBAAO;AACP,YAAI,CAAC,MAAM;AACT,iBAAO,IAAI,MAAM,kBAAkB,CAAC;AACpC;AAAA,QACF;AACA,gBAAQ,IAAI;AAAA,MACd;AACA,YAAM,MAAK;AAAA,IACb,SAAS,OAAO;AACd,aAAO,KAAK;AAAA,IACd;AAAA,EACF,CAAC;AACH;AACA,MAAM,aAAa,CAAC,SAAS,MAAM,SAAS;AAC1C,QAAM,OAAO,OAAO,YAAY,WAAW,IAAI,KAAK,CAAC,OAAO,GAAG,EAAE,KAAI,CAAE,IAAI;AAC3E,QAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,QAAM,IAAI,SAAS,cAAc,GAAG;AACpC,IAAE,OAAO;AACT,IAAE,WAAW;AACb,IAAE,MAAK;AACP,MAAI,gBAAgB,GAAG;AACzB;ACvjBO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,CAAC,eAAe,gBAAgB,IAAIC,MAAAA,SAAyB,IAAI;AACvE,QAAM,CAAC,WAAW,YAAY,IAAIA,MAAAA,SAAS,IAAI;AAC/C,QAAM,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAS,KAAK;AACtD,QAAM,CAAC,eAAe,gBAAgB,IAAIA,MAAAA,SAAmD,MAAM;AACnG,QAAM,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAwB,IAAI;AACpE,QAAM,qBAAqBM,MAAAA,OAA8B,IAAI;AAC7D,QAAM,kBAAkBA,MAAAA,OAAsB,IAAI;AAGlDL,QAAAA,UAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,mBAAmB,SAAS;AAC9B,sBAAc,mBAAmB,OAAO;AAAA,MAC1C;AAAA,IACF;AAAA,EACF,GAAG,CAAA,CAAE;AAEL,QAAM,cAAc,MAAM;AACxB,QAAI,mBAAmB,SAAS;AAC9B,oBAAc,mBAAmB,OAAO;AACxC,yBAAmB,UAAU;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,eAAe,OAAO,UAAkB;AAC5C,QAAI,CAAC,mBAAmB;AACtB;AAAA,IACF;AACA,qBAAiB,SAAS;AAC1B,oBAAgB,IAAI;AACpB,oBAAgB,IAAI;AAEpB,UAAM,OAAO,YAAY;AACvB,UAAI;AACF,cAAM,WAAW,MAAM,kBAAkB,KAAK;AAG9C,YAAI,SAAS,WAAW,aAAa;AACnC,sBAAA;AACA,2BAAiB,SAAS;AAC1B,0BAAgB,KAAK;AAGrB,iCAAuB,SAAS,aAAa,EAAE;AAG/C,qBAAW,MAAM;AACf,6BAAiB,MAAM;AAAA,UACzB,GAAG,GAAI;AAAA,QACT,WAAW,SAAS,WAAW,WAAW;AAAA,QAE1C,WAAW,SAAS,WAAW,UAAU;AACvC,sBAAA;AACA,2BAAiB,OAAO;AACxB,0BAAgB,KAAK;AACrB,0BAAgB,SAAS,SAAS,8BAA8B;AAChE,kBAAQ,MAAM,+BAA+B,SAAS,KAAK;AAAA,QAC7D;AAAA,MACF,SAAS,OAAO;AACd,oBAAA;AACA,yBAAiB,OAAO;AACxB,wBAAgB,KAAK;AACrB,wBAAgB,iBAAiB,QAAQ,MAAM,UAAU,+BAA+B;AACxF,gBAAQ,MAAM,gCAAgC,KAAK;AAAA,MACrD;AAAA,IACF;AAGA,UAAM,KAAA;AACN,uBAAmB,UAAU,YAAY,MAAM,GAAI;AAAA,EACrD;AAEA,QAAM,0BAA0B,YAAY;AAC1C,QAAI,EAAE,2BAA2BU,SAAAA,eAAe;AAC9C;AAAA,IACF;AAEA,UAAM,eAAe;AAGrB,QAAI;AACF,YAAM,QAAQ,MAAM,oBAAoB,YAAY;AACpD,UAAI,CAAC,OAAO;AACV,yBAAiB,OAAO;AACxB,wBAAgB,KAAK;AACrB,wBAAgB,qCAAqC;AACrD,gBAAQ,MAAM,iEAAiE;AAC/E;AAAA,MACF;AACA,sBAAgB,UAAU;AAC1B,YAAM,aAAa,KAAK;AAAA,IAC1B,SAAS,OAAO;AACd,uBAAiB,OAAO;AACxB,sBAAgB,KAAK;AACrB,sBAAgB,iBAAiB,QAAQ,MAAM,UAAU,qCAAqC;AAC9F,cAAQ,MAAM,+BAA+B,KAAK;AAAA,IACpD;AAAA,EACF;AAEA,QAAM,aAAa,YAAY;AAC7B,iBAAa,IAAI;AACjB,QAAI,2BAA2BA,SAAAA,cAAc;AAC3C,YAAM,eAAe;AACrB,YAAM,WAAW,aAAa,OAAA;AAC9B,UAAI,UAAU;AACZ,YAAI;AACF,gBAAM,gBAAgB,MAAM,SAAS,QAAQ;AAC7C,2BAAiB,aAAa;AAAA,QAChC,SAAS,OAAO;AACd,kBAAQ,MAAM,yBAAyB,KAAK;AAC5C,2BAAiB,KAAK;AAAA,QACxB;AAAA,MACF,OAAO;AACL,yBAAiB,KAAK;AAAA,MACxB;AAAA,IACF,OAAO;AACL,uBAAiB,KAAK;AAAA,IACxB;AACA,iBAAa,KAAK;AAAA,EACpB;AAEAV,QAAAA,UAAU,MAAM;AACd,eAAA;AAEA,gBAAA;AACA,qBAAiB,MAAM;AACvB,oBAAgB,KAAK;AACrB,oBAAgB,IAAI;AAAA,EACtB,GAAG,CAAC,eAAe,CAAC;AAEpB,SACEH,2BAAAA,KAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,eAAc,UAAA,4BAAwB;AAAA,IAGpD,aACCA,2BAAAA,IAAC,OAAA,EAAI,WAAU,iBACb,UAAAA,2BAAAA,IAAC,OAAA,EAAI,WAAU,eACb,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,MAAAC,2BAAAA,IAACoB,cAAA,EAAQ,WAAU,gCAAA,CAAgC;AAAA,MACnDpB,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAmB,UAAA,wBAAA,CAAqB;AAAA,IAAA,EAAA,CACvD,GACF,GACF;AAAA,IAID,CAAC,aAAa,kBAAkB,wCAC9B,OAAA,EAAI,WAAU,iBACb,UAAAA,2BAAAA,IAAC,SAAI,WAAU,eACb,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAQ,WAAU,mBAAA,CAAmB;AAAA,MACtCA,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAmB,UAAA,qCAAA,CAAkC;AAAA,IAAA,EAAA,CACpE,GACF,GACF;AAAA,IAID,CAAC,aAAa,kBAAkB,QAAQ,kBAAkB,UAAU,CAAC,gBACpEA,2BAAAA,IAAC,SAAI,WAAU,iBACb,yCAAC,OAAA,EAAI,WAAU,eACb,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,SAAA,EAAQ,WAAU,mBAAA,CAAmB;AAAA,MACtCA,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAmB,UAAA,iDAAA,CAA8C;AAAA,IAAA,EAAA,CAChF,GACF,GACF;AAAA,IAID,CAAC,aAAa,gBAAgB,kBAAkB,4CAC9C,OAAA,EAAI,WAAU,iBACb,UAAAA,2BAAAA,IAAC,SAAI,WAAU,eACb,UAAAD,gCAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,MAAAC,2BAAAA,IAACoB,cAAA,EAAQ,WAAU,gCAAA,CAAgC;AAAA,MACnDpB,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAmB,UAAA,sCAAA,CAAmC;AAAA,IAAA,EAAA,CACrE,GACF,GACF;AAAA,IAID,CAAC,aAAa,kBAAkB,4CAC9B,OAAA,EAAI,WAAU,iBACb,UAAAA,2BAAAA,IAAC,SAAI,WAAU,eACb,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,MAAAC,2BAAAA,IAACiC,aAAA,EAAa,WAAU,oBAAmB,OAAM,0BAAyB;AAAA,MAC1EjC,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAmB,UAAA,oCAAA,CAAiC;AAAA,IAAA,EAAA,CACnE,GACF,GACF;AAAA,IAID,CAAC,aAAa,kBAAkB,0CAC9B,OAAA,EAAI,WAAU,iBACb,UAAAA,2BAAAA,IAAC,SAAI,WAAU,eACb,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,MAAAC,2BAAAA,IAACkC,SAAA,EAAQ,WAAU,oBAAmB,OAAM,wBAAuB;AAAA,MACnElC,2BAAAA,IAAC,KAAA,EAAE,WAAU,oBAAoB,0BAAgB,+BAAA,CAA+B;AAAA,IAAA,EAAA,CAClF,GACF,GACF;AAAA,IAID,CAAC,aACAA,2BAAAA,IAAC,OAAA,EAAI,WAAU,sBACb,UAAAA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS;AAAA,QACT,UAAU,CAAC,iBAAiB;AAAA,QAC5B,WAAU;AAAA,QAET,yBAAe,kBAAkB;AAAA,MAAA;AAAA,IAAA,EACpC,CACF;AAAA,EAAA,GAEJ;AAEJ;AC5NO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAkC;AAChC,MAAI,CAAC,iBAAiB;AACpB,WACEA,2BAAAA,IAAC,OAAA,EAAI,WAAU,mBACb,yCAAC,OAAA,EAAI,WAAU,qBACb,UAAAA,2BAAAA,IAAC,MAAA,EAAG,WAAU,oBAAmB,UAAA,mCAAA,CAAgC,GACnE,GACF;AAAA,EAEJ;AAEA,MAAI,gBAAgB,QAAA,MAAc,WAAW;AAC3C,WACEA,2BAAAA,IAAC,OAAA,EAAI,WAAU,mBACb,yCAAC,OAAA,EAAI,WAAU,qBACb,UAAAA,2BAAAA,IAAC,MAAA,EAAG,WAAU,oBAAmB,UAAA,8BAAA,CAA2B,GAC9D,GACF;AAAA,EAEJ;AAEA,SACED,2BAAAA,KAAA+B,qBAAA,EAEG,UAAA;AAAA,IAAA,iBAAiB,mBAChB9B,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,IAKH,iBAAiB,oBAChBA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,IAKH,iBAAiB,kBAChBA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,IAKH,iBAAiB,gBAChBA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,IAIF,iBAAiB,wBACfA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GAGN;AAEJ;ACrFA,MAAM,qBAAqB,CAAC,iBAAgC;AAC1D,QAAM,EAAE,QAAQ,QAAA,IAAYI,4BAAA;AAC5B,QAAM,CAAC,aAAa,cAAc,IAAIH,MAAAA,SAAS,EAAE;AACjD,QAAM,gBAAgB,YAAY;AAChC,QAAI;AACJ,QAAI,6CAAc,aAAa;AAC7B,gBAAU,MAAM,aAAa,YAAA;AAAA,IAC/B,OAAO;AACL,YAAM,OAAO,MAAM,SAAS,kBAAkB;AAC9C,YAAM,OAAO,MAAM,KAAK,KAAA;AACxB,qBAAe,KAAK,IAAI;AACxB,gBAAU,KAAK,MAAM,IAAI;AAAA,IAC3B;AACA,YAAQ,IAAI,UAAU,MAAM;AAC5B,WAAO,YAAY,OAAO;AAAA,EAC5B;AAEA,QAAM,gBAAgB,YAAY;AAChC,QAAI;AACJ,QAAI,aAAa;AACf,iBAAW;AAAA,IACb,OAAO;AACL,iBAAW,OAAO,+BAA+B,KAAK;AACtD,iBAAW,WAAW;AACtB,qBAAe,QAAQ;AAAA,IACzB;AACA,SAAI,6CAAc,gBAAe,SAAS;AACxC,YAAM,aAAa,YAAY,SAAS,QAAQ;AAAA,IAClD,OAAO;AACL,YAAM,OAAO,MAAM;AAAA,QACjB,KAAK,UAAU,OAAO;AAAA,QACtB;AAAA,QACA;AAAA,MAAA;AAEF,UAAI,MAAM;AACR,gBAAQ,IAAI,cAAc,IAAI;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB,YAAY;;AAChC,SAAI,6CAAc,gBAAe,SAAS;AACxC,YAAM,aAAa,YAAY,SAAS;AAAA,QACtC,SAAS;AAAA,QACT,KAAK;AAAA,QACL,YAAY;AAAA,UACV,QAAO,kBAAa,eAAb,mBAAyB;AAAA,UAChC,SAAQ,kBAAa,eAAb,mBAAyB;AAAA,QAAA;AAAA,MACnC,CACD;AAAA,IACH,OAAO;AACH,YAAM,yCAAyC;AAAA,IACnD;AAAA,EACF;AAQA,QAAM,sBAAsB,OAAO,iBAA+B;AAEhE,QAAI,6CAAc,2BAA2B;AAC3C,YAAM,UAAU,aAAa;AAC7B,YAAM,QAAQ,MAAM,QAAQ,kBAAkB,cAAc,OAAsB;AAClF,aAAO;AAAA,IACT;AACA,UAAM,+CAA+C;AACrD,WAAO;AAAA,EACT;AAEA,QAAM,yBAAyB,CAAC,cAA+B;;AAC7D,UAAM,sBAAqB,kDAAc,8BAAd,mBAAyC,2BAA2B;AAC/F,QAAI,oBAAoB;AACtB,aAAO,YAAY,kBAAkB;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,oBAAoB,OAAO,UAAkB;AACjD,QAAI,6CAAc,2BAA2B;AAC3C,YAAM,UAAU,aAAa;AAC7B,aAAO,MAAM,QAAQ,iBAAiB,KAAK;AAAA,IAC7C;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,IAAA;AAAA,EAEX;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AChGA,MAAM,uBAAuB,CAAC,iBAAgC;AAC5D,QAAM,EAAE,QAAQ,QAAA,IAAYG,4BAAA;AAK5B,QAAM,sBAAsB,OAAO,iBAA+B;AAEhE,QAAI,6CAAc,2BAA2B;AAC3C,YAAM,UAAU,aAAa;AAC7B,YAAM,QAAQ,MAAM,QAAQ;AAAA,QAC1B;AAAA,QACA;AAAA,MAAA;AAEF,aAAO;AAAA,IACT;AACA,UAAM,+CAA+C;AACrD,WAAO;AAAA,EACT;AAEA,QAAM,yBAAyB,CAAC,cAA+B;;AAC7D,UAAM,sBACJ,kDAAc,8BAAd,mBAAyC;AAAA,MACvC;AAAA;AAEJ,QAAI,oBAAoB;AACtB,aAAO,YAAY,kBAAkB;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,oBAAoB,OAAO,UAAkB;AACjD,QAAI,6CAAc,2BAA2B;AAC3C,YAAM,UAAU,aAAa;AAC7B,aAAO,MAAM,QAAQ,iBAAiB,KAAK;AAAA,IAC7C;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,IAAA;AAAA,EAEX;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;ACrBO,SAAS,YAAY,EAAE,gBAAiD;;AAC7E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE,iBAAA;AACJ,QAAM,EAAE,iBAAiB,mBAAA,IAAuBA,4BAAA;AAChD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE,mBAAmB,YAAY;AAEnC,QAAM,EAAE,qBAAqB,wBAAwB,kBAAA,IACnD,qBAAqB,YAAY;AAEnC,QAAM,mBAAiCuB,MAAAA;AAAAA,IACrC,OAAO;AAAA,MACL,YAAY;AAAA,MACZ,GAAI,gBAAgB,CAAA;AAAA,MACpB,YAAY;AAAA,QACV,IAAI,6CAAc,eAAc,CAAA;AAAA,QAChC,OAAO,gBAAgB;AAAA,QACvB,QAAQ,gBAAgB;AAAA,MAAA;AAAA,IAC1B;AAAA,IAEF,CAAC,iBAAiB,YAAY;AAAA,EAAA;AAGhC,SACE3B,2BAAAA,IAAC,eAAA,EACC,UAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oBAEb,UAAA;AAAA,IAAAC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGFD,2BAAAA,KAAC,OAAA,EAAI,WAAU,kBAEb,UAAA;AAAA,MAAAC,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA;AAAA,QAAA;AAAA,MAAA;AAAA,MAIFA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAAA;AAAA,qCAID,QAAA,EAAK,WAAU,kBACd,UAAAA,+BAAC,OAAA,EAAI,WAAU,kBACb,UAAAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,YAAU,sBAAiB,gBAAjB,mBAA8B,aAAY;AAAA,UAAA;AAAA,UAGtD,UAAAA,2BAAAA,IAAC,aAAA,EAAY,cAAc,iBAAA,CAAkB;AAAA,QAAA;AAAA,MAAA,GAEjD,EAAA,CACF;AAAA,MAGAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAAA;AAAA,MAIFA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAAA;AAAA,IACF,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;;;;;;;;;;;;;;;;","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]}