@orangecatai/adgen-canvas 0.0.22 → 0.0.24

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.
Files changed (54) hide show
  1. package/dist/dev/{chunk-OIMA545L.js → chunk-3IT4IPF5.js} +23 -13
  2. package/dist/dev/chunk-3IT4IPF5.js.map +7 -0
  3. package/dist/dev/{chunk-4K5LIQQU.js → chunk-LIELFD5T.js} +2 -1
  4. package/dist/dev/chunk-LIELFD5T.js.map +7 -0
  5. package/dist/dev/{chunk-DG4DHKBY.js → chunk-T44CUBOH.js} +2 -2
  6. package/dist/dev/data/{image-AWVYCS2V.js → image-CVNEYNEF.js} +3 -3
  7. package/dist/dev/index.css +854 -0
  8. package/dist/dev/index.css.map +3 -3
  9. package/dist/dev/index.js +4276 -1645
  10. package/dist/dev/index.js.map +4 -4
  11. package/dist/dev/locales/{en-IMRJ2ODG.js → en-VCZQBJ2N.js} +2 -2
  12. package/dist/dev/subset-shared.chunk.js +1 -1
  13. package/dist/dev/subset-worker.chunk.js +1 -1
  14. package/dist/prod/{chunk-TX6PVFUX.js → chunk-CLQPYXMS.js} +1 -1
  15. package/dist/prod/{chunk-PJYEU4Z2.js → chunk-MFGXKFLH.js} +1 -1
  16. package/dist/prod/chunk-ZXE5XSJO.js +4 -0
  17. package/dist/prod/data/image-7TLJ6VAY.js +1 -0
  18. package/dist/prod/index.css +1 -1
  19. package/dist/prod/index.js +109 -65
  20. package/dist/prod/locales/{en-5WIO63S4.js → en-ZZURI326.js} +1 -1
  21. package/dist/prod/subset-shared.chunk.js +1 -1
  22. package/dist/prod/subset-worker.chunk.js +1 -1
  23. package/dist/types/common/src/constants.d.ts +4 -0
  24. package/dist/types/element/src/Scene.d.ts +1 -1
  25. package/dist/types/element/src/frame.d.ts +2 -2
  26. package/dist/types/element/src/newElement.d.ts +10 -1
  27. package/dist/types/element/src/typeChecks.d.ts +2 -1
  28. package/dist/types/element/src/types.d.ts +17 -2
  29. package/dist/types/excalidraw/actions/actionFrame.d.ts +41 -0
  30. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +41 -0
  31. package/dist/types/excalidraw/components/AIChatPanel.d.ts +34 -0
  32. package/dist/types/excalidraw/components/App.d.ts +10 -0
  33. package/dist/types/excalidraw/components/ImageGeneratorPanel.d.ts +14 -0
  34. package/dist/types/excalidraw/components/VideoElement.d.ts +9 -0
  35. package/dist/types/excalidraw/components/VideoGeneratorPanel.d.ts +149 -0
  36. package/dist/types/excalidraw/components/ai-chat/canvasTools.d.ts +79 -0
  37. package/dist/types/excalidraw/components/auto-resize/autoResizeEngine.d.ts +1 -0
  38. package/dist/types/excalidraw/components/icons.d.ts +2 -0
  39. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +4 -0
  40. package/dist/types/excalidraw/data/blob.d.ts +4 -1
  41. package/dist/types/excalidraw/index.d.ts +4 -2
  42. package/dist/types/excalidraw/scene/types.d.ts +1 -0
  43. package/dist/types/excalidraw/types.d.ts +50 -0
  44. package/dist/types/excalidraw/utils/brandContextUtils.d.ts +4 -1
  45. package/dist/types/excalidraw/utils/videoApi.d.ts +30 -0
  46. package/dist/types/utils/src/shape.d.ts +2 -2
  47. package/package.json +3 -3
  48. package/dist/dev/chunk-4K5LIQQU.js.map +0 -7
  49. package/dist/dev/chunk-OIMA545L.js.map +0 -7
  50. package/dist/prod/chunk-X4HZUT4M.js +0 -4
  51. package/dist/prod/data/image-YCVSAMH5.js +0 -1
  52. /package/dist/dev/{chunk-DG4DHKBY.js.map → chunk-T44CUBOH.js.map} +0 -0
  53. /package/dist/dev/data/{image-AWVYCS2V.js.map → image-CVNEYNEF.js.map} +0 -0
  54. /package/dist/dev/locales/{en-IMRJ2ODG.js.map → en-VCZQBJ2N.js.map} +0 -0
@@ -1 +1 @@
1
- import{A,B,C,D,E,F,G,H,I,J,K,L,M,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}from"../chunk-TX6PVFUX.js";import"../chunk-SRAX5OIU.js";export{f as alerts,e as buttons,l as canvasError,G as chat,s as clearCanvasDialog,C as colorPicker,A as colors,K as commandPalette,v as confirmDialog,M as default,i as element,b as elementLink,x as encrypted,p as errorDialog,m as errorSplash,g as errors,q as exportDialog,I as fontList,j as headings,r as helpDialog,k as hints,w as imageExportDialog,L as keys,a as labels,c as library,E as mermaid,D as overwriteConfirm,t as publishDialog,u as publishSuccessDialog,H as quickSearch,o as roomDialog,d as search,n as shareDialog,y as stats,z as toast,h as toolBar,F as ttd,J as userList,B as welcomeScreen};
1
+ import{A,B,C,D,E,F,G,H,I,J,K,L,M,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}from"../chunk-CLQPYXMS.js";import"../chunk-SRAX5OIU.js";export{f as alerts,e as buttons,l as canvasError,G as chat,s as clearCanvasDialog,C as colorPicker,A as colors,K as commandPalette,v as confirmDialog,M as default,i as element,b as elementLink,x as encrypted,p as errorDialog,m as errorSplash,g as errors,q as exportDialog,I as fontList,j as headings,r as helpDialog,k as hints,w as imageExportDialog,L as keys,a as labels,c as library,E as mermaid,D as overwriteConfirm,t as publishDialog,u as publishSuccessDialog,H as quickSearch,o as roomDialog,d as search,n as shareDialog,y as stats,z as toast,h as toolBar,F as ttd,J as userList,B as welcomeScreen};
@@ -1 +1 @@
1
- import{a,b,c,d}from"./chunk-Z5NKEFVG.js";import"./chunk-PJYEU4Z2.js";import"./chunk-SRAX5OIU.js";export{a as Commands,b as subsetToBase64,c as subsetToBinary,d as toBase64};
1
+ import{a,b,c,d}from"./chunk-Z5NKEFVG.js";import"./chunk-MFGXKFLH.js";import"./chunk-SRAX5OIU.js";export{a as Commands,b as subsetToBase64,c as subsetToBinary,d as toBase64};
@@ -1 +1 @@
1
- import{a as r,c as t}from"./chunk-Z5NKEFVG.js";import"./chunk-PJYEU4Z2.js";import"./chunk-SRAX5OIU.js";var s=import.meta.url?new URL(import.meta.url):void 0;typeof window>"u"&&typeof self<"u"&&(self.onmessage=async e=>{switch(e.data.command){case r.Subset:let a=await t(e.data.arrayBuffer,e.data.codePoints);self.postMessage(a,{transfer:[a]});break}});export{s as WorkerUrl};
1
+ import{a as r,c as t}from"./chunk-Z5NKEFVG.js";import"./chunk-MFGXKFLH.js";import"./chunk-SRAX5OIU.js";var s=import.meta.url?new URL(import.meta.url):void 0;typeof window>"u"&&typeof self<"u"&&(self.onmessage=async e=>{switch(e.data.command){case r.Subset:let a=await t(e.data.arrayBuffer,e.data.codePoints);self.postMessage(a,{transfer:[a]});break}});export{s as WorkerUrl};
@@ -175,6 +175,10 @@ export declare const IMAGE_MIME_TYPES: {
175
175
  readonly avif: "image/avif";
176
176
  readonly jfif: "image/jfif";
177
177
  };
178
+ export declare const VIDEO_MIME_TYPES: {
179
+ readonly mp4: "video/mp4";
180
+ readonly mov: "video/quicktime";
181
+ };
178
182
  export declare const STRING_MIME_TYPES: {
179
183
  readonly text: "text/plain";
180
184
  readonly html: "text/html";
@@ -70,7 +70,7 @@ export declare class Scene {
70
70
  getElementIndex(elementId: string): number;
71
71
  getContainerElement: (element: (ExcalidrawElement & {
72
72
  containerId: ExcalidrawElement["id"] | null;
73
- }) | null) => import("@orangecatai/element/types").ExcalidrawLinearElement | import("@orangecatai/element/types").ExcalidrawSelectionElement | import("@orangecatai/element/types").ExcalidrawRectangleElement | import("@orangecatai/element/types").ExcalidrawDiamondElement | import("@orangecatai/element/types").ExcalidrawEllipseElement | import("@orangecatai/element/types").ExcalidrawEmbeddableElement | import("@orangecatai/element/types").ExcalidrawIframeElement | import("@orangecatai/element/types").ExcalidrawImageElement | import("@orangecatai/element/types").ExcalidrawFrameElement | import("@orangecatai/element/types").ExcalidrawMagicFrameElement | import("@orangecatai/element/types").ExcalidrawTextElement | import("@orangecatai/element/types").ExcalidrawFreeDrawElement | null;
73
+ }) | null) => import("@orangecatai/element/types").ExcalidrawLinearElement | import("@orangecatai/element/types").ExcalidrawSelectionElement | import("@orangecatai/element/types").ExcalidrawRectangleElement | import("@orangecatai/element/types").ExcalidrawDiamondElement | import("@orangecatai/element/types").ExcalidrawEllipseElement | import("@orangecatai/element/types").ExcalidrawEmbeddableElement | import("@orangecatai/element/types").ExcalidrawIframeElement | import("@orangecatai/element/types").ExcalidrawImageElement | import("@orangecatai/element/types").ExcalidrawVideoElement | import("@orangecatai/element/types").ExcalidrawFrameElement | import("@orangecatai/element/types").ExcalidrawMagicFrameElement | import("@orangecatai/element/types").ExcalidrawTextElement | import("@orangecatai/element/types").ExcalidrawFreeDrawElement | null;
74
74
  getElementsFromId: (id: string) => ExcalidrawElement[];
75
75
  mutateElement<TElement extends Mutable<ExcalidrawElement>>(element: TElement, updates: ElementUpdate<TElement>, options?: {
76
76
  informMutation: boolean;
@@ -31,8 +31,8 @@ export declare const getFrameLikeElements: (allElements: ExcalidrawElementsInclu
31
31
  */
32
32
  export declare const getRootElements: (allElements: ExcalidrawElementsIncludingDeleted) => ExcalidrawElement[];
33
33
  export declare const getElementsInResizingFrame: (allElements: ExcalidrawElementsIncludingDeleted, frame: ExcalidrawFrameLikeElement, appState: AppState, elementsMap: ElementsMap) => ExcalidrawElement[];
34
- export declare const getElementsInNewFrame: (elements: ExcalidrawElementsIncludingDeleted, frame: ExcalidrawFrameLikeElement, elementsMap: ElementsMap) => (import("./types").ExcalidrawLinearElement | import("./types").ExcalidrawSelectionElement | import("./types").ExcalidrawRectangleElement | import("./types").ExcalidrawDiamondElement | import("./types").ExcalidrawEllipseElement | import("./types").ExcalidrawEmbeddableElement | import("./types").ExcalidrawIframeElement | import("./types").ExcalidrawImageElement | import("./types").ExcalidrawFrameElement | import("./types").ExcalidrawMagicFrameElement | import("./types").ExcalidrawTextElement | import("./types").ExcalidrawFreeDrawElement)[];
35
- export declare const omitPartialGroups: (elements: ExcalidrawElement[], frame: ExcalidrawFrameLikeElement, allElementsMap: ElementsMap) => (import("./types").ExcalidrawLinearElement | import("./types").ExcalidrawSelectionElement | import("./types").ExcalidrawRectangleElement | import("./types").ExcalidrawDiamondElement | import("./types").ExcalidrawEllipseElement | import("./types").ExcalidrawEmbeddableElement | import("./types").ExcalidrawIframeElement | import("./types").ExcalidrawImageElement | import("./types").ExcalidrawFrameElement | import("./types").ExcalidrawMagicFrameElement | import("./types").ExcalidrawTextElement | import("./types").ExcalidrawFreeDrawElement)[];
34
+ export declare const getElementsInNewFrame: (elements: ExcalidrawElementsIncludingDeleted, frame: ExcalidrawFrameLikeElement, elementsMap: ElementsMap) => (import("./types").ExcalidrawLinearElement | import("./types").ExcalidrawSelectionElement | import("./types").ExcalidrawRectangleElement | import("./types").ExcalidrawDiamondElement | import("./types").ExcalidrawEllipseElement | import("./types").ExcalidrawEmbeddableElement | import("./types").ExcalidrawIframeElement | import("./types").ExcalidrawImageElement | import("./types").ExcalidrawVideoElement | import("./types").ExcalidrawFrameElement | import("./types").ExcalidrawMagicFrameElement | import("./types").ExcalidrawTextElement | import("./types").ExcalidrawFreeDrawElement)[];
35
+ export declare const omitPartialGroups: (elements: ExcalidrawElement[], frame: ExcalidrawFrameLikeElement, allElementsMap: ElementsMap) => (import("./types").ExcalidrawLinearElement | import("./types").ExcalidrawSelectionElement | import("./types").ExcalidrawRectangleElement | import("./types").ExcalidrawDiamondElement | import("./types").ExcalidrawEllipseElement | import("./types").ExcalidrawEmbeddableElement | import("./types").ExcalidrawIframeElement | import("./types").ExcalidrawImageElement | import("./types").ExcalidrawVideoElement | import("./types").ExcalidrawFrameElement | import("./types").ExcalidrawMagicFrameElement | import("./types").ExcalidrawTextElement | import("./types").ExcalidrawFreeDrawElement)[];
36
36
  export declare const getContainingFrame: (element: ExcalidrawElement, elementsMap: ElementsMap) => ExcalidrawFrameLikeElement | null;
37
37
  /** */
38
38
  export declare const filterElementsEligibleAsFrameChildren: (elements: readonly ExcalidrawElement[], frame: ExcalidrawFrameLikeElement) => ExcalidrawElement[];
@@ -1,5 +1,5 @@
1
1
  import type { MarkOptional } from "@orangecatai/common/utility-types";
2
- import type { ExcalidrawImageElement, ExcalidrawTextElement, ExcalidrawLinearElement, ExcalidrawGenericElement, NonDeleted, TextAlign, VerticalAlign, Arrowhead, ExcalidrawFreeDrawElement, FontFamilyValues, ExcalidrawTextContainer, ExcalidrawFrameElement, ExcalidrawEmbeddableElement, ExcalidrawMagicFrameElement, ExcalidrawIframeElement, ElementsMap, ExcalidrawArrowElement, ExcalidrawElbowArrowElement, ExcalidrawLineElement } from "./types";
2
+ import type { ExcalidrawImageElement, ExcalidrawVideoElement, ExcalidrawTextElement, ExcalidrawLinearElement, ExcalidrawGenericElement, NonDeleted, TextAlign, VerticalAlign, Arrowhead, ExcalidrawFreeDrawElement, FontFamilyValues, ExcalidrawTextContainer, ExcalidrawFrameElement, ExcalidrawEmbeddableElement, ExcalidrawMagicFrameElement, ExcalidrawIframeElement, ElementsMap, ExcalidrawArrowElement, ExcalidrawElbowArrowElement, ExcalidrawLineElement } from "./types";
3
3
  export type ElementConstructorOpts = MarkOptional<Omit<ExcalidrawGenericElement, "id" | "type" | "isDeleted" | "updated">, "width" | "height" | "angle" | "groupIds" | "frameId" | "index" | "boundElements" | "seed" | "version" | "versionNonce" | "link" | "strokeStyle" | "fillStyle" | "strokeColor" | "backgroundColor" | "roughness" | "strokeWidth" | "roundness" | "locked" | "opacity" | "customData">;
4
4
  export declare const newElement: (opts: {
5
5
  type: ExcalidrawGenericElement["type"];
@@ -60,3 +60,12 @@ export declare const newImageElement: (opts: {
60
60
  scale?: ExcalidrawImageElement["scale"];
61
61
  crop?: ExcalidrawImageElement["crop"];
62
62
  } & ElementConstructorOpts) => NonDeleted<ExcalidrawImageElement>;
63
+ export declare const newVideoElement: (opts: {
64
+ status?: ExcalidrawVideoElement["status"];
65
+ videoUrl?: ExcalidrawVideoElement["videoUrl"];
66
+ mimeType?: ExcalidrawVideoElement["mimeType"];
67
+ thumbnailDataUrl?: ExcalidrawVideoElement["thumbnailDataUrl"];
68
+ duration?: ExcalidrawVideoElement["duration"];
69
+ naturalWidth?: ExcalidrawVideoElement["naturalWidth"];
70
+ naturalHeight?: ExcalidrawVideoElement["naturalHeight"];
71
+ } & ElementConstructorOpts) => NonDeleted<ExcalidrawVideoElement>;
@@ -1,8 +1,9 @@
1
1
  import type { ElementOrToolType } from "@orangecatai/adgen-canvas/types";
2
2
  import type { MarkNonNullable } from "@orangecatai/common/utility-types";
3
- import type { ExcalidrawElement, ExcalidrawTextElement, ExcalidrawEmbeddableElement, ExcalidrawLinearElement, ExcalidrawBindableElement, ExcalidrawFreeDrawElement, InitializedExcalidrawImageElement, ExcalidrawImageElement, ExcalidrawTextElementWithContainer, ExcalidrawTextContainer, ExcalidrawFrameElement, RoundnessType, ExcalidrawFrameLikeElement, ExcalidrawElementType, ExcalidrawIframeElement, ExcalidrawIframeLikeElement, ExcalidrawMagicFrameElement, ExcalidrawArrowElement, ExcalidrawElbowArrowElement, ExcalidrawLineElement, ExcalidrawFlowchartNodeElement, ExcalidrawLinearElementSubType } from "./types";
3
+ import type { ExcalidrawElement, ExcalidrawTextElement, ExcalidrawEmbeddableElement, ExcalidrawLinearElement, ExcalidrawBindableElement, ExcalidrawFreeDrawElement, InitializedExcalidrawImageElement, ExcalidrawImageElement, ExcalidrawTextElementWithContainer, ExcalidrawTextContainer, ExcalidrawFrameElement, RoundnessType, ExcalidrawFrameLikeElement, ExcalidrawElementType, ExcalidrawIframeElement, ExcalidrawIframeLikeElement, ExcalidrawMagicFrameElement, ExcalidrawArrowElement, ExcalidrawElbowArrowElement, ExcalidrawLineElement, ExcalidrawFlowchartNodeElement, ExcalidrawLinearElementSubType, ExcalidrawVideoElement } from "./types";
4
4
  export declare const isInitializedImageElement: (element: ExcalidrawElement | null) => element is InitializedExcalidrawImageElement;
5
5
  export declare const isImageElement: (element: ExcalidrawElement | null) => element is ExcalidrawImageElement;
6
+ export declare const isVideoElement: (element: ExcalidrawElement | null | undefined) => element is ExcalidrawVideoElement;
6
7
  export declare const isEmbeddableElement: (element: ExcalidrawElement | null | undefined) => element is ExcalidrawEmbeddableElement;
7
8
  export declare const isIframeElement: (element: ExcalidrawElement | null) => element is ExcalidrawIframeElement;
8
9
  export declare const isIframeLikeElement: (element: ExcalidrawElement | null) => element is ExcalidrawIframeLikeElement;
@@ -137,6 +137,21 @@ export type ExcalidrawImageElement = _ExcalidrawElementBase & Readonly<{
137
137
  crop: ImageCrop | null;
138
138
  }>;
139
139
  export type InitializedExcalidrawImageElement = MarkNonNullable<ExcalidrawImageElement, "fileId">;
140
+ export type ExcalidrawVideoElement = _ExcalidrawElementBase & Readonly<{
141
+ type: "video";
142
+ /** URL to host-stored video file (not DataURL — videos are too large for base64) */
143
+ videoUrl: string | null;
144
+ status: "idle" | "uploading" | "saved" | "error";
145
+ mimeType: "video/mp4" | "video/quicktime" | null;
146
+ /** JPEG data URL of the first frame, used as the static thumbnail on canvas */
147
+ thumbnailDataUrl: string | null;
148
+ /** Total duration in seconds */
149
+ duration: number;
150
+ /** Original video pixel width */
151
+ naturalWidth: number;
152
+ /** Original video pixel height */
153
+ naturalHeight: number;
154
+ }>;
140
155
  export type ExcalidrawFrameElement = _ExcalidrawElementBase & {
141
156
  type: "frame";
142
157
  name: string | null;
@@ -151,13 +166,13 @@ export type ExcalidrawFrameLikeElement = ExcalidrawFrameElement | ExcalidrawMagi
151
166
  */
152
167
  export type ExcalidrawGenericElement = ExcalidrawSelectionElement | ExcalidrawRectangleElement | ExcalidrawDiamondElement | ExcalidrawEllipseElement;
153
168
  export type ExcalidrawFlowchartNodeElement = ExcalidrawRectangleElement | ExcalidrawDiamondElement | ExcalidrawEllipseElement;
154
- export type ExcalidrawRectanguloidElement = ExcalidrawRectangleElement | ExcalidrawImageElement | ExcalidrawTextElement | ExcalidrawFreeDrawElement | ExcalidrawIframeLikeElement | ExcalidrawFrameLikeElement | ExcalidrawEmbeddableElement | ExcalidrawSelectionElement;
169
+ export type ExcalidrawRectanguloidElement = ExcalidrawRectangleElement | ExcalidrawImageElement | ExcalidrawVideoElement | ExcalidrawTextElement | ExcalidrawFreeDrawElement | ExcalidrawIframeLikeElement | ExcalidrawFrameLikeElement | ExcalidrawEmbeddableElement | ExcalidrawSelectionElement;
155
170
  /**
156
171
  * ExcalidrawElement should be JSON serializable and (eventually) contain
157
172
  * no computed data. The list of all ExcalidrawElements should be shareable
158
173
  * between peers and contain no state local to the peer.
159
174
  */
160
- export type ExcalidrawElement = ExcalidrawGenericElement | ExcalidrawTextElement | ExcalidrawLinearElement | ExcalidrawArrowElement | ExcalidrawFreeDrawElement | ExcalidrawImageElement | ExcalidrawFrameElement | ExcalidrawMagicFrameElement | ExcalidrawIframeElement | ExcalidrawEmbeddableElement;
175
+ export type ExcalidrawElement = ExcalidrawGenericElement | ExcalidrawTextElement | ExcalidrawLinearElement | ExcalidrawArrowElement | ExcalidrawFreeDrawElement | ExcalidrawImageElement | ExcalidrawVideoElement | ExcalidrawFrameElement | ExcalidrawMagicFrameElement | ExcalidrawIframeElement | ExcalidrawEmbeddableElement;
161
176
  export type ExcalidrawNonSelectionElement = Exclude<ExcalidrawElement, ExcalidrawSelectionElement>;
162
177
  export type Ordered<TElement extends ExcalidrawElement> = TElement & {
163
178
  index: FractionalIndex;
@@ -1201,6 +1201,47 @@ export declare const actionWrapSelectionInFrame: {
1201
1201
  link: string | null;
1202
1202
  locked: boolean;
1203
1203
  customData?: Record<string, any>;
1204
+ }> & Readonly<{
1205
+ type: "video";
1206
+ videoUrl: string | null;
1207
+ status: "idle" | "uploading" | "saved" | "error";
1208
+ mimeType: "video/mp4" | "video/quicktime" | null;
1209
+ thumbnailDataUrl: string | null;
1210
+ duration: number;
1211
+ naturalWidth: number;
1212
+ naturalHeight: number;
1213
+ }> & {
1214
+ index: import("@orangecatai/element/types").FractionalIndex;
1215
+ }) | (Readonly<{
1216
+ id: string;
1217
+ x: number;
1218
+ y: number;
1219
+ strokeColor: string;
1220
+ backgroundColor: string;
1221
+ fillStyle: import("@orangecatai/element/types").FillStyle;
1222
+ strokeWidth: number;
1223
+ strokeStyle: import("@orangecatai/element/types").StrokeStyle;
1224
+ roundness: null | {
1225
+ type: import("@orangecatai/element/types").RoundnessType;
1226
+ value?: number;
1227
+ };
1228
+ roughness: number;
1229
+ opacity: number;
1230
+ width: number;
1231
+ height: number;
1232
+ angle: import("@orangecatai/math").Radians;
1233
+ seed: number;
1234
+ version: number;
1235
+ versionNonce: number;
1236
+ index: import("@orangecatai/element/types").FractionalIndex | null;
1237
+ isDeleted: boolean;
1238
+ groupIds: readonly import("@orangecatai/element/types").GroupId[];
1239
+ frameId: string | null;
1240
+ boundElements: readonly import("@orangecatai/element/types").BoundElement[] | null;
1241
+ updated: number;
1242
+ link: string | null;
1243
+ locked: boolean;
1244
+ customData?: Record<string, any>;
1204
1245
  }> & {
1205
1246
  type: "frame";
1206
1247
  name: string | null;
@@ -531,6 +531,47 @@ export declare const actionTogglePolygon: {
531
531
  link: string | null;
532
532
  locked: boolean;
533
533
  customData?: Record<string, any>;
534
+ }> & Readonly<{
535
+ type: "video";
536
+ videoUrl: string | null;
537
+ status: "idle" | "uploading" | "saved" | "error";
538
+ mimeType: "video/mp4" | "video/quicktime" | null;
539
+ thumbnailDataUrl: string | null;
540
+ duration: number;
541
+ naturalWidth: number;
542
+ naturalHeight: number;
543
+ }> & {
544
+ index: import("@orangecatai/element/types").FractionalIndex;
545
+ }) | (Readonly<{
546
+ id: string;
547
+ x: number;
548
+ y: number;
549
+ strokeColor: string;
550
+ backgroundColor: string;
551
+ fillStyle: import("@orangecatai/element/types").FillStyle;
552
+ strokeWidth: number;
553
+ strokeStyle: import("@orangecatai/element/types").StrokeStyle;
554
+ roundness: null | {
555
+ type: import("@orangecatai/element/types").RoundnessType;
556
+ value?: number;
557
+ };
558
+ roughness: number;
559
+ opacity: number;
560
+ width: number;
561
+ height: number;
562
+ angle: import("@orangecatai/math").Radians;
563
+ seed: number;
564
+ version: number;
565
+ versionNonce: number;
566
+ index: import("@orangecatai/element/types").FractionalIndex | null;
567
+ isDeleted: boolean;
568
+ groupIds: readonly import("@orangecatai/element/types").GroupId[];
569
+ frameId: string | null;
570
+ boundElements: readonly import("@orangecatai/element/types").BoundElement[] | null;
571
+ updated: number;
572
+ link: string | null;
573
+ locked: boolean;
574
+ customData?: Record<string, any>;
534
575
  }> & {
535
576
  type: "frame";
536
577
  name: string | null;
@@ -115,6 +115,15 @@ export type AIChatPanelProps = {
115
115
  tags: string[];
116
116
  assetType: string;
117
117
  blobUrl: string;
118
+ previewDataUrl?: string;
119
+ }>>;
120
+ onSearchAdCreatives?: (query: string) => Promise<Array<{
121
+ id: string;
122
+ name: string;
123
+ tags: string[];
124
+ mimeType: string;
125
+ blobUrl: string;
126
+ previewDataUrl?: string;
118
127
  }>>;
119
128
  onListBrandTemplates?: (keywords?: string[]) => Promise<Array<{
120
129
  id: string;
@@ -124,10 +133,35 @@ export type AIChatPanelProps = {
124
133
  width?: number;
125
134
  height?: number;
126
135
  thumbnailBlobUrl?: string;
136
+ thumbnailDataUrl?: string;
127
137
  }>>;
128
138
  onGetTemplateVariant?: (variantId: string) => Promise<{
129
139
  canvasJson: string;
130
140
  }>;
141
+ /**
142
+ * Searches brand assets, ad creatives, and templates by keywords, returning
143
+ * top 3 matches with base64 preview images. Used by the visual agent's
144
+ * `find_brand_asset` tool and the @mention autocomplete.
145
+ */
146
+ onFindBrandAssets?: (type: "image-asset" | "ad-creative" | "template", keywords: string[]) => Promise<{
147
+ results: Array<{
148
+ id: string;
149
+ name: string;
150
+ tags?: string[];
151
+ width?: number | null;
152
+ height?: number | null;
153
+ previewDataUrl: string;
154
+ }>;
155
+ }>;
156
+ /**
157
+ * Called when user types after `@` in the chat input. Should return a
158
+ * lightweight list of matching items (no base64 — previews fetched on pick).
159
+ */
160
+ onMentionSearch?: (query: string) => Promise<Array<{
161
+ id: string;
162
+ type: "image-asset" | "ad-creative" | "template";
163
+ name: string;
164
+ }>>;
131
165
  /**
132
166
  * OpenRouter model tag for the reviewer agent. Must be vision-capable.
133
167
  * Defaults to the same model as chatModel.
@@ -258,6 +258,7 @@ declare class App extends React.Component<AppProps, AppState> {
258
258
  private updateEmbedValidationStatus;
259
259
  private updateEmbeddables;
260
260
  private renderEmbeddables;
261
+ private renderVideos;
261
262
  private getFrameNameDOMId;
262
263
  frameNameBoundsCache: FrameNameBoundsCache;
263
264
  private resetEditingFrame;
@@ -284,11 +285,17 @@ declare class App extends React.Component<AppProps, AppState> {
284
285
  private onIframeSrcCopy;
285
286
  onMagicframeToolSelect: () => void;
286
287
  onImageGeneratorSelect: () => void;
288
+ onVideoGeneratorSelect: () => void;
287
289
  /**
288
290
  * Inserts a generated image (base64 data URL) into a frame element,
289
291
  * sized to fill the frame exactly. Used by the image generator panel.
290
292
  */
291
293
  insertGeneratedImageIntoFrame: (dataURL: string, frameElement: import("@orangecatai/element/types").ExcalidrawFrameLikeElement & import("@orangecatai/element/types").NonDeletedExcalidrawElement) => Promise<void>;
294
+ /**
295
+ * Inserts a generated video (presigned/CDN URL) into a video-generator frame,
296
+ * replacing any previous video. The video element fills the frame exactly.
297
+ */
298
+ insertGeneratedVideoIntoFrame: (videoUrl: string, frameElement: import("@orangecatai/element/types").ExcalidrawFrameLikeElement & import("@orangecatai/element/types").NonDeletedExcalidrawElement) => void;
292
299
  /**
293
300
  * Inserts a generated image near a source element (≥ 25 px clearance).
294
301
  * Tries right → below → left → above; falls back to right if all collide.
@@ -532,6 +539,7 @@ declare class App extends React.Component<AppProps, AppState> {
532
539
  */
533
540
  private getLatestInitializedImageElement;
534
541
  private onImageToolbarButtonClick;
542
+ onVideoToolbarButtonClick: () => void;
535
543
  private getImageNaturalDimensions;
536
544
  /** updates image cache, refreshing updated elements and/or setting status
537
545
  to error for images that fail during <img> element creation */
@@ -545,6 +553,8 @@ declare class App extends React.Component<AppProps, AppState> {
545
553
  private clearSelection;
546
554
  private handleInteractiveCanvasRef;
547
555
  private insertImages;
556
+ private newVideoPlaceholder;
557
+ insertVideos: (videoFiles: File[], sceneX: number, sceneY: number) => Promise<void>;
548
558
  private handleAppOnDrop;
549
559
  loadFileToCanvas: (file: File, fileHandle: FileSystemHandle | null) => Promise<void>;
550
560
  private handleCanvasContextMenu;
@@ -16,6 +16,20 @@ export declare const MODEL_CONFIG: {
16
16
  readonly supportedResolutions: readonly ["0.5K", "1K", "2K", "4K"];
17
17
  readonly supportedRatios: readonly ["21:9", "16:9", "4:3", "3:2", "1:1", "9:16", "3:4", "2:3", "5:4", "4:5", "4:1", "1:4", "8:1", "1:8"];
18
18
  };
19
+ readonly "nano banana lite": {
20
+ readonly modelId: "google/gemini-3.1-flash-lite-image";
21
+ readonly textOutput: true;
22
+ readonly supportsImageSize: false;
23
+ readonly supportedResolutions: readonly ["0.5K", "1K", "2K", "4K"];
24
+ readonly supportedRatios: readonly ["21:9", "16:9", "4:3", "3:2", "1:1", "9:16", "3:4", "2:3", "5:4", "4:5", "4:1", "1:4", "8:1", "1:8"];
25
+ };
26
+ readonly "nano banana 2 lite": {
27
+ readonly modelId: "google/gemini-3.1-flash-lite-image";
28
+ readonly textOutput: true;
29
+ readonly supportsImageSize: false;
30
+ readonly supportedResolutions: readonly ["0.5K", "1K", "2K", "4K"];
31
+ readonly supportedRatios: readonly ["21:9", "16:9", "4:3", "3:2", "1:1", "9:16", "3:4", "2:3", "5:4", "4:5", "4:1", "1:4", "8:1", "1:8"];
32
+ };
19
33
  readonly "nano banana pro": {
20
34
  readonly modelId: "google/gemini-3-pro-image-preview";
21
35
  readonly textOutput: true;
@@ -0,0 +1,9 @@
1
+ import type { ExcalidrawVideoElement } from "@orangecatai/element/types";
2
+ import "./VideoElement.scss";
3
+ interface VideoElementProps {
4
+ element: ExcalidrawVideoElement;
5
+ isActive: boolean;
6
+ videoDownloadProxyUrl?: string;
7
+ }
8
+ export declare const VideoElement: ({ element, videoDownloadProxyUrl }: VideoElementProps) => import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,149 @@
1
+ import "./VideoGeneratorPanel.scss";
2
+ import type { ExcalidrawFrameLikeElement, NonDeletedExcalidrawElement } from "@orangecatai/element/types";
3
+ import type { AppClassProperties } from "../types";
4
+ declare const VIDEO_MODEL_CONFIG: {
5
+ readonly "veo 3.1 fast": {
6
+ readonly modelId: "google/veo-3.1-fast";
7
+ readonly supportsFirstFrame: true;
8
+ readonly supportsLastFrame: true;
9
+ readonly audioMode: "always-on";
10
+ readonly supportsDuration: true;
11
+ readonly durationMode: "choices";
12
+ readonly durationValues: readonly [4, 6, 8];
13
+ readonly supportsResolution: true;
14
+ readonly supportedResolutions: readonly ["720p", "1080p", "4K"];
15
+ readonly supportsNegativePrompt: false;
16
+ readonly supportedRatios: readonly ["16:9", "9:16"];
17
+ readonly frameInputMode: "dual-frame";
18
+ readonly supportsInputReferences: false;
19
+ readonly supportsSeed: true;
20
+ };
21
+ readonly "veo 3.1 lite": {
22
+ readonly modelId: "google/veo-3.1-lite";
23
+ readonly supportsFirstFrame: true;
24
+ readonly supportsLastFrame: true;
25
+ readonly audioMode: "always-on";
26
+ readonly supportsDuration: true;
27
+ readonly durationMode: "choices";
28
+ readonly durationValues: readonly [4, 6, 8];
29
+ readonly supportsResolution: true;
30
+ readonly supportedResolutions: readonly ["720p", "1080p"];
31
+ readonly supportsNegativePrompt: false;
32
+ readonly supportedRatios: readonly ["16:9", "9:16"];
33
+ readonly frameInputMode: "dual-frame";
34
+ readonly supportsInputReferences: false;
35
+ readonly supportsSeed: true;
36
+ };
37
+ readonly "kling v3 pro": {
38
+ readonly modelId: "kwaivgi/kling-v3.0-pro";
39
+ readonly supportsFirstFrame: true;
40
+ readonly supportsLastFrame: true;
41
+ readonly audioMode: "toggle";
42
+ readonly supportsDuration: true;
43
+ readonly durationMode: "slider";
44
+ readonly minDuration: 3;
45
+ readonly maxDuration: 15;
46
+ readonly supportsResolution: false;
47
+ readonly supportsNegativePrompt: true;
48
+ readonly supportedRatios: readonly ["16:9", "9:16", "1:1"];
49
+ readonly frameInputMode: "dual-frame";
50
+ readonly supportsInputReferences: false;
51
+ readonly supportsSeed: true;
52
+ };
53
+ readonly "kling v3 std": {
54
+ readonly modelId: "kwaivgi/kling-v3.0-std";
55
+ readonly supportsFirstFrame: true;
56
+ readonly supportsLastFrame: true;
57
+ readonly audioMode: "toggle";
58
+ readonly supportsDuration: true;
59
+ readonly durationMode: "slider";
60
+ readonly minDuration: 3;
61
+ readonly maxDuration: 15;
62
+ readonly supportsResolution: false;
63
+ readonly supportsNegativePrompt: true;
64
+ readonly supportedRatios: readonly ["16:9", "9:16", "1:1"];
65
+ readonly frameInputMode: "dual-frame";
66
+ readonly supportsInputReferences: false;
67
+ readonly supportsSeed: true;
68
+ };
69
+ readonly "seedance 2.0": {
70
+ readonly modelId: "bytedance/seedance-2.0";
71
+ readonly supportsFirstFrame: true;
72
+ readonly supportsLastFrame: true;
73
+ readonly audioMode: "always-on";
74
+ readonly supportsDuration: true;
75
+ readonly durationMode: "slider";
76
+ readonly minDuration: 4;
77
+ readonly maxDuration: 15;
78
+ readonly supportsResolution: true;
79
+ readonly supportedResolutions: readonly ["480p", "720p", "1080p", "4K"];
80
+ readonly supportsNegativePrompt: false;
81
+ readonly supportedRatios: readonly ["16:9", "9:16", "1:1", "4:3", "3:4", "21:9", "9:21"];
82
+ readonly frameInputMode: "dual-frame";
83
+ readonly supportsInputReferences: true;
84
+ readonly supportsSeed: true;
85
+ };
86
+ readonly "seedance 2.0 fast": {
87
+ readonly modelId: "bytedance/seedance-2.0-fast";
88
+ readonly supportsFirstFrame: true;
89
+ readonly supportsLastFrame: true;
90
+ readonly audioMode: "always-on";
91
+ readonly supportsDuration: true;
92
+ readonly durationMode: "slider";
93
+ readonly minDuration: 4;
94
+ readonly maxDuration: 15;
95
+ readonly supportsResolution: true;
96
+ readonly supportedResolutions: readonly ["480p", "720p"];
97
+ readonly supportsNegativePrompt: false;
98
+ readonly supportedRatios: readonly ["16:9", "9:16", "1:1", "4:3", "3:4", "21:9", "9:21"];
99
+ readonly frameInputMode: "dual-frame";
100
+ readonly supportsInputReferences: true;
101
+ readonly supportsSeed: true;
102
+ };
103
+ readonly "happyhorse 1.1": {
104
+ readonly modelId: "alibaba/happyhorse-1.1";
105
+ readonly supportsFirstFrame: true;
106
+ readonly supportsLastFrame: false;
107
+ readonly audioMode: "none";
108
+ readonly supportsDuration: true;
109
+ readonly durationMode: "slider";
110
+ readonly minDuration: 3;
111
+ readonly maxDuration: 15;
112
+ readonly supportsResolution: true;
113
+ readonly supportedResolutions: readonly ["720p", "1080p"];
114
+ readonly supportsNegativePrompt: false;
115
+ readonly supportedRatios: readonly ["16:9", "9:16", "1:1", "4:3", "3:4", "21:9", "9:21"];
116
+ readonly frameInputMode: "start-only";
117
+ readonly supportsInputReferences: false;
118
+ readonly supportsSeed: true;
119
+ };
120
+ readonly "grok video": {
121
+ readonly modelId: "x-ai/grok-imagine-video";
122
+ readonly supportsFirstFrame: true;
123
+ readonly supportsLastFrame: false;
124
+ readonly audioMode: "none";
125
+ readonly supportsDuration: true;
126
+ readonly durationMode: "slider";
127
+ readonly minDuration: 1;
128
+ readonly maxDuration: 15;
129
+ readonly supportsResolution: true;
130
+ readonly supportedResolutions: readonly ["480p", "720p"];
131
+ readonly supportsNegativePrompt: false;
132
+ readonly supportedRatios: readonly ["16:9", "9:16", "1:1", "4:3", "3:4", "3:2", "2:3"];
133
+ readonly frameInputMode: "start-only";
134
+ readonly supportsInputReferences: false;
135
+ readonly supportsSeed: true;
136
+ };
137
+ };
138
+ export type VideoModelName = keyof typeof VIDEO_MODEL_CONFIG;
139
+ export declare const VIDEO_MODEL_NAMES: VideoModelName[];
140
+ export declare const VideoGeneratorPanel: ({ element, app, onBeforeVideoGen, onAfterVideoGen, }: {
141
+ element: NonDeletedExcalidrawElement & ExcalidrawFrameLikeElement;
142
+ app: AppClassProperties;
143
+ onBeforeVideoGen?: () => Promise<{
144
+ allowed: boolean;
145
+ error?: string;
146
+ }>;
147
+ onAfterVideoGen?: () => void;
148
+ }) => import("react/jsx-runtime").JSX.Element | null;
149
+ export {};
@@ -449,6 +449,23 @@ export declare const BANNER_TOOLS: readonly [{
449
449
  readonly additionalProperties: false;
450
450
  };
451
451
  };
452
+ }, {
453
+ readonly type: "function";
454
+ readonly function: {
455
+ readonly name: "search_ad_creatives";
456
+ readonly description: "Search uploaded ad creatives (past static ads) by name or tag keywords. Returns top 3 matches with visual previews. Use this to find reference ads for inspiration or remixing.";
457
+ readonly parameters: {
458
+ readonly type: "object";
459
+ readonly properties: {
460
+ readonly query: {
461
+ readonly type: "string";
462
+ readonly description: "Search query — name or tag keywords";
463
+ };
464
+ };
465
+ readonly required: readonly ["query"];
466
+ readonly additionalProperties: false;
467
+ };
468
+ };
452
469
  }, {
453
470
  readonly type: "function";
454
471
  readonly function: {
@@ -568,6 +585,48 @@ export declare const BANNER_TOOLS: readonly [{
568
585
  readonly additionalProperties: false;
569
586
  };
570
587
  };
588
+ }, {
589
+ readonly type: "function";
590
+ readonly function: {
591
+ readonly name: "place_brand_asset";
592
+ readonly description: "Place a brand image asset or ad creative directly into a frame as an image element. Use after search_brand_assets or search_ad_creatives to insert the found asset. Maintains the asset's aspect ratio inside the frame.";
593
+ readonly parameters: {
594
+ readonly type: "object";
595
+ readonly properties: {
596
+ readonly frameId: {
597
+ readonly type: "string";
598
+ readonly description: "The frame to place the asset in";
599
+ };
600
+ readonly assetId: {
601
+ readonly type: "string";
602
+ readonly description: "Asset ID from search_brand_assets or search_ad_creatives [id:...] field";
603
+ };
604
+ readonly assetType: {
605
+ readonly type: "string";
606
+ readonly enum: readonly ["image-asset", "ad-creative"];
607
+ readonly description: "Type of asset — defaults to image-asset";
608
+ };
609
+ readonly x: {
610
+ readonly type: "number";
611
+ readonly description: "X offset from frame left edge (optional, centers by default)";
612
+ };
613
+ readonly y: {
614
+ readonly type: "number";
615
+ readonly description: "Y offset from frame top edge (optional, centers by default)";
616
+ };
617
+ readonly width: {
618
+ readonly type: "number";
619
+ readonly description: "Width of placed image (optional, auto-fits to frame by default)";
620
+ };
621
+ readonly height: {
622
+ readonly type: "number";
623
+ readonly description: "Height of placed image (optional, auto-fits to frame by default)";
624
+ };
625
+ };
626
+ readonly required: readonly ["frameId", "assetId"];
627
+ readonly additionalProperties: false;
628
+ };
629
+ };
571
630
  }];
572
631
  export declare function serializeElements(elements: readonly ExcalidrawElement[]): Record<string, unknown>[];
573
632
  export type FrameInfo = {
@@ -643,6 +702,15 @@ export type ToolExecutionContext = {
643
702
  tags: string[];
644
703
  assetType: string;
645
704
  blobUrl: string;
705
+ previewDataUrl?: string;
706
+ }>>;
707
+ onSearchAdCreatives?: (query: string) => Promise<Array<{
708
+ id: string;
709
+ name: string;
710
+ tags: string[];
711
+ mimeType: string;
712
+ blobUrl: string;
713
+ previewDataUrl?: string;
646
714
  }>>;
647
715
  onListBrandTemplates?: (keywords?: string[]) => Promise<Array<{
648
716
  id: string;
@@ -652,10 +720,21 @@ export type ToolExecutionContext = {
652
720
  width?: number;
653
721
  height?: number;
654
722
  thumbnailBlobUrl?: string;
723
+ thumbnailDataUrl?: string;
655
724
  }>>;
656
725
  onGetTemplateVariant?: (variantId: string) => Promise<{
657
726
  canvasJson: string;
658
727
  }>;
728
+ onFindBrandAssets?: (type: "image-asset" | "ad-creative" | "template", keywords: string[]) => Promise<{
729
+ results: Array<{
730
+ id: string;
731
+ name: string;
732
+ tags?: string[];
733
+ width?: number | null;
734
+ height?: number | null;
735
+ previewDataUrl: string;
736
+ }>;
737
+ }>;
659
738
  /**
660
739
  * Internal cache: populated by execGetTemplateVariant so that
661
740
  * execLoadTemplateIntoFrame can reuse the already-fetched JSON without a
@@ -179,6 +179,7 @@ export declare function runAutoResize(opts: {
179
179
  logo?: string;
180
180
  fontPreview?: string;
181
181
  fontUrl?: string;
182
+ name?: string;
182
183
  };
183
184
  }): Promise<DimensionResult[]>;
184
185
  export {};
@@ -33,6 +33,7 @@ export declare const FreedrawIcon: import("react/jsx-runtime").JSX.Element;
33
33
  export declare const TextIcon: import("react/jsx-runtime").JSX.Element;
34
34
  export declare const TextSizeIcon: import("react/jsx-runtime").JSX.Element;
35
35
  export declare const ImageIcon: import("react/jsx-runtime").JSX.Element;
36
+ export declare const VideoIcon: import("react/jsx-runtime").JSX.Element;
36
37
  export declare const EraserIcon: import("react/jsx-runtime").JSX.Element;
37
38
  export declare const ZoomInIcon: import("react/jsx-runtime").JSX.Element;
38
39
  export declare const ZoomOutIcon: import("react/jsx-runtime").JSX.Element;
@@ -189,6 +190,7 @@ export declare const eyeDropperIcon: import("react/jsx-runtime").JSX.Element;
189
190
  export declare const extraToolsIcon: import("react/jsx-runtime").JSX.Element;
190
191
  export declare const frameToolIcon: import("react/jsx-runtime").JSX.Element;
191
192
  export declare const imageGeneratorToolIcon: import("react/jsx-runtime").JSX.Element;
193
+ export declare const videoGeneratorToolIcon: import("react/jsx-runtime").JSX.Element;
192
194
  export declare const mermaidLogoIcon: import("react/jsx-runtime").JSX.Element;
193
195
  export declare const RetryIcon: import("react/jsx-runtime").JSX.Element;
194
196
  export declare const stackPushIcon: import("react/jsx-runtime").JSX.Element;