{"version":3,"sources":["../src/components/DragHandles.tsx","../src/plugins/baseCanvas.ts","../src/plugins/ReactCanvas.tsx","../src/components/InfiniteCanvas.tsx","../src/hooks/useAutomaticCanvasSize.ts","../src/utils/pointUtils.ts","../src/plugins/PluginSystem.ts","../src/plugins/pointerPlugin.ts","../src/utils/mouseUtils.ts","../src/utils/dragHandleUtils.ts","../src/components/GradientHandles.tsx","../src/plugins/gradientEditorPlugin.ts","../src/utils/isMoving.ts","../src/components/Marquee.tsx","../src/plugins/marqueePlugin.ts","../src/utils/selectionUtils.ts","../src/components/PointHandles.tsx","../src/components/SelectionRect.tsx","../src/components/SnapLines.tsx","../src/hooks/useMultipleClickCount.ts","../src/plugins/domEventPlugin.ts","../src/plugins/domTextPlugin.ts","../src/plugins/doubleClickPlugin.ts","../src/plugins/drawingPlugin.ts","../src/plugins/editTextPlugin.ts","../src/utils/textSelection.ts","../src/plugins/eraserPlugin.ts","../src/plugins/focusPlugin.ts","../src/plugins/gradientEditorUtils.ts","../src/plugins/highlightPlugin.ts","../src/plugins/linePlugin.ts","../src/plugins/movePlugin.ts","../src/utils/movingUtils.ts","../src/utils/snapUtils.ts","../src/plugins/panPlugin.ts","../src/utils/wheelUtils.ts","../src/plugins/pointPlugin.ts","../src/plugins/scalePlugin.ts","../src/utils/scalingUtils.ts","../src/plugins/selectionPlugin.ts","../src/plugins/zoomPlugin.ts","../src/utils/animationUtils.ts","../src/utils/zoomUtils.ts","../src/utils/elementUtils.ts","../src/utils/viewportUtils.ts"],"sourcesContent":["import { insetRect, Rect } from \"@noya-app/noya-geometry\";\nimport { Group, Rectangle } from \"@noya-app/noya-graphics\";\nimport React, { useMemo } from \"react\";\nimport { BaseCanvasData, getCanvasTransform } from \"../plugins/baseCanvas\";\nimport { useReactCanvas } from \"../plugins/ReactCanvas\";\nimport { ScaleData } from \"../plugins/scalePlugin\";\nimport { getDragHandles } from \"../utils/dragHandleUtils\";\n\nexport function DragHandles({\n  selectionRect,\n  data,\n}: {\n  selectionRect?: Rect;\n  data?: Pick<BaseCanvasData, \"zoom\" | \"origin\"> &\n    Pick<ScaleData, \"dragHandleSize\" | \"hoveredDragHandleDirection\">;\n}) {\n  const ReactCanvas = useReactCanvas();\n  const canvasData = ReactCanvas.useData() as ScaleData & BaseCanvasData;\n\n  data = data ?? canvasData;\n\n  const transform = useMemo(() => getCanvasTransform(data), [data]);\n\n  const dragHandles = useMemo(() => {\n    return selectionRect\n      ? getDragHandles({\n          selectionRect,\n          data: { zoom: data.zoom, dragHandleSize: data.dragHandleSize },\n        })\n      : [];\n  }, [selectionRect, data.zoom, data.dragHandleSize]);\n\n  return (\n    <Group transform={transform}>\n      {dragHandles.map((handle) => {\n        const inset = 0.5 / data.zoom;\n        const rect = insetRect(handle.rect, inset);\n\n        return (\n          <React.Fragment key={handle.compassDirection}>\n            <Rectangle\n              rect={rect}\n              paint={{\n                style: \"fill\",\n                color: \"#FFFFFF\",\n              }}\n            />\n            <Rectangle\n              rect={rect}\n              paint={{\n                style: \"stroke\",\n                strokeWidth: handle.strokeWidth,\n                color:\n                  data.hoveredDragHandleDirection === handle.compassDirection\n                    ? \"#FFA500\"\n                    : \"#1E90FF\",\n              }}\n            />\n          </React.Fragment>\n        );\n      })}\n    </Group>\n  );\n}\n","import { AffineTransform, Point, Size } from \"@noya-app/noya-geometry\";\nimport React from \"react\";\nimport { BaseMode, Plugin, PluginSystem } from \"./PluginSystem\";\nimport { BaseContextProperties } from \"./contextProperties\";\nimport { PointerData } from \"./pointerPlugin\";\n\nexport type BaseCanvasData = { size: Size; zoom: number; origin: Point };\n\nexport type AnyCanvasPlugin = Plugin<\n  BaseMode,\n  BaseCanvasData & PointerData,\n  any,\n  ReactEventHandlerMap\n>;\n\nexport type AnyCanvasPluginSystem = PluginSystem<\n  BaseMode,\n  BaseCanvasData & PointerData,\n  any,\n  ReactEventHandlerMap\n>;\n\nexport const initialBaseCanvasData: BaseCanvasData = {\n  size: { width: 0, height: 0 },\n  zoom: 1,\n  origin: { x: 0, y: 0 },\n};\n\nexport const initialPointerData: PointerData = {\n  pointer: undefined,\n  pointerDown: undefined,\n  clickCount: 0,\n  lastClickTime: 0,\n  rawPointer: undefined,\n};\n\nexport type ReactEventHandlerMap = {\n  onWheel: (event: React.WheelEvent) => void;\n  onPointerEnter: (event: React.PointerEvent) => void;\n  onPointerLeave: (event: React.PointerEvent) => void;\n  onPointerDown: (event: React.PointerEvent) => void;\n  onPointerMove: (event: React.PointerEvent) => void;\n  onPointerUp: (event: React.PointerEvent) => void;\n  onPointerCancel: (event: React.PointerEvent) => void;\n  onGotPointerCapture: (event: React.PointerEvent) => void;\n  onLostPointerCapture: (event: React.PointerEvent) => void;\n  onKeyDown: (event: React.KeyboardEvent) => void;\n  onKeyUp: (event: React.KeyboardEvent) => void;\n\n  // Special, not handled by React's event system\n  // TODO: Move this elsewhere?\n  onBeforeInput: (event: InputEvent) => void;\n};\n\nexport function createCanvasPlugin<\n  Mode extends BaseMode,\n  Data extends object,\n  ContextProperties extends object,\n>(\n  plugin: Omit<\n    Plugin<\n      Mode,\n      Data,\n      ContextProperties & BaseContextProperties<Mode, Data>,\n      ReactEventHandlerMap\n    >,\n    \"getCursor\"\n  > & {\n    getCursor?: ({\n      data,\n      mode,\n    }: {\n      data: Data;\n      mode: Mode;\n    }) => string | undefined;\n  }\n) {\n  return {\n    ...(plugin as Plugin<\n      Mode,\n      Data,\n      ContextProperties & BaseContextProperties<Mode, Data>,\n      ReactEventHandlerMap\n    >),\n    data: {\n      ...initialBaseCanvasData,\n      ...plugin.data,\n    },\n  };\n}\n\nexport function getCanvasTransform(data: {\n  origin: { x: number; y: number };\n  zoom: number;\n}) {\n  return AffineTransform.translate(data.origin.x, data.origin.y).scale(\n    data.zoom\n  );\n}\n","import { Size } from \"@noya-app/noya-geometry\";\nimport {\n  getCurrentPlatform,\n  handleKeyboardEvent,\n  KeyMap,\n} from \"@noya-app/noya-keymap\";\nimport { isDeepEqual } from \"@noya-app/noya-utils\";\nimport { assignRef, useLateReferenceState } from \"@noya-app/react-utils\";\nimport React, {\n  ComponentProps,\n  forwardRef,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\nimport { InfiniteCanvas } from \"../components/InfiniteCanvas\";\nimport { convertOffsetPoint, convertPoint } from \"../utils/pointUtils\";\nimport {\n  BaseMode,\n  Plugin,\n  PluginSystem,\n  PluginSystemContextProperties,\n  PluginSystemData,\n  PluginSystemEventHandlerMap,\n  PluginSystemMode,\n  PluginSystemOptions,\n} from \"./PluginSystem\";\nimport {\n  AnyCanvasPlugin,\n  AnyCanvasPluginSystem,\n  BaseCanvasData,\n  getCanvasTransform,\n  initialBaseCanvasData,\n  initialPointerData,\n  ReactEventHandlerMap,\n} from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  DOMContextProperties,\n} from \"./contextProperties\";\nimport {\n  PointerData,\n  pointerPlugin,\n  UniquePointerContextProperties,\n} from \"./pointerPlugin\";\n\ntype AllBaseContextProperties<\n  Mode extends BaseMode,\n  Data extends BaseCanvasData & PointerData,\n> = BaseContextProperties<Mode, Data> & DOMContextProperties;\n\ntype ContextPropertiesWithoutBase<\n  Mode extends BaseMode,\n  Data extends BaseCanvasData & PointerData,\n  ContextProperties extends object,\n> = Omit<ContextProperties, keyof AllBaseContextProperties<Mode, Data>>;\n\n// Fix covariance/contravariance\ntype ContextPropertiesBaseFixType<\n  Mode extends BaseMode,\n  Data extends BaseCanvasData & PointerData,\n  ContextProperties extends object,\n> = ContextPropertiesWithoutBase<Mode, Data, ContextProperties> &\n  AllBaseContextProperties<Mode, Data>;\n\ntype PluginSystemToReactCanvas<PS extends AnyCanvasPluginSystem> = ReactCanvas<\n  PluginSystemMode<PS>,\n  PluginSystemData<PS>,\n  PluginSystemContextProperties<PS>,\n  PluginSystemEventHandlerMap<PS>\n>;\n\nconst AnyDataContext = React.createContext<\n  (BaseCanvasData & PointerData) | undefined\n>(undefined);\nconst AnyModeContext = React.createContext<BaseMode | undefined>(undefined);\nconst AnyContextPropertiesContext = React.createContext<\n  ContextPropertiesBaseFixType<any, any, any> | undefined\n>(undefined);\n\nexport class ReactCanvas<\n  Mode extends BaseMode,\n  Data extends BaseCanvasData & PointerData,\n  ContextProperties extends object,\n  EventHandlerMap extends ReactEventHandlerMap,\n> {\n  private constructor(\n    public pluginSystem: PluginSystem<\n      Mode,\n      Data,\n      ContextProperties,\n      EventHandlerMap\n    >\n  ) {}\n\n  static create() {\n    return new ReactCanvas(\n      PluginSystem.create()\n        .addData(initialBaseCanvasData)\n        .addData(initialPointerData)\n    );\n  }\n\n  addPlugin<\n    M extends BaseMode,\n    D extends BaseCanvasData & PointerData,\n    H extends object,\n    E extends ReactEventHandlerMap,\n  >(plugin: Plugin<M, D, H, E>) {\n    return new ReactCanvas(this.pluginSystem.clone().addPlugin(plugin));\n  }\n\n  addPlugins<P extends AnyCanvasPlugin[]>(\n    ...plugins: P\n  ): PluginSystemToReactCanvas<CanvasPluginsToSystem<P>>;\n  addPlugins(...plugins: AnyCanvasPlugin[]) {\n    const newPluginSystem = plugins.reduce(\n      (pluginSystem, plugin) => pluginSystem.addPlugin(plugin),\n      this.pluginSystem.clone() as AnyCanvasPluginSystem\n    );\n\n    return new ReactCanvas(newPluginSystem);\n  }\n\n  addOptions(options: PluginSystemOptions<ContextProperties>) {\n    return new ReactCanvas(this.pluginSystem.clone().addOptions(options));\n  }\n\n  get initialMode() {\n    return this.pluginSystem.mode;\n  }\n\n  get initialData() {\n    return this.pluginSystem.data;\n  }\n\n  PropertiesRefContext = AnyContextPropertiesContext as React.Context<\n    ContextPropertiesBaseFixType<Mode, Data, ContextProperties> | undefined\n  >;\n\n  ModeContext = AnyModeContext as React.Context<Mode | undefined>;\n\n  DataContext = AnyDataContext as React.Context<Data | undefined>;\n\n  ModeProvider = this.ModeContext.Provider;\n\n  DataProvider = this.DataContext.Provider;\n\n  useContextPropertiesRef = () => {\n    const context = useContext(this.PropertiesRefContext);\n    if (!context) {\n      throw new Error(\n        \"usePropertiesRefContext must be used within a CanvasProvider\"\n      );\n    }\n    return context;\n  };\n\n  useMode = () => {\n    const context = useContext(this.ModeContext);\n    if (!context) {\n      throw new Error(\"useModeContext must be used within a CanvasProvider\");\n    }\n    return context;\n  };\n\n  useData = () => {\n    const context = useContext(this.DataContext);\n    if (!context) {\n      throw new Error(\"useDataContext must be used within a CanvasProvider\");\n    }\n    return context;\n  };\n\n  Canvas = forwardRef(\n    (\n      {\n        mode: modeProp,\n        data: dataProp,\n        contextProperties: withoutBase,\n        setMode: setModeProp,\n        setData: setDataProp,\n        children,\n        InfiniteCanvasComponent = InfiniteCanvas,\n        ...rest\n      }: {\n        mode?: Mode;\n        data?: Data;\n        contextProperties: (\n          base: BaseContextProperties<Mode, Data>\n        ) => ContextPropertiesWithoutBase<Mode, Data, ContextProperties> &\n          UniquePointerContextProperties;\n        setMode?: (mode: Mode) => void;\n        setData?: (data: Data) => void;\n        children?: React.ReactNode;\n        InfiniteCanvasComponent?: typeof InfiniteCanvas;\n      } & Omit<\n        React.ComponentProps<typeof InfiniteCanvas>,\n        \"onChangeSize\" | \"children\"\n      >,\n      forwardedRef: React.Ref<HTMLDivElement>\n    ) => {\n      const [internalMode, setInternalMode] = useState<Mode>(\n        modeProp ?? this.initialMode\n      );\n      const [internalData, setInternalData] = useState<Data>(\n        dataProp ?? this.initialData\n      );\n\n      const [mode, setMode_] =\n        modeProp !== undefined && setModeProp\n          ? [modeProp, setModeProp]\n          : [internalMode, setInternalMode];\n\n      const [data, setData_] =\n        dataProp !== undefined && setDataProp\n          ? [dataProp, setDataProp]\n          : [internalData, setInternalData];\n\n      const [getMode, setMode] = useLateReferenceState(mode, setMode_);\n      const [getData, setData] = useLateReferenceState(data, setData_);\n\n      const {\n        PropertiesRefContext: HandlerContext,\n        ModeContext,\n        DataContext,\n      } = this;\n\n      const canvasRef = useRef<HTMLDivElement>(null);\n\n      const base = useMemo(\n        (): BaseContextProperties<Mode, Data> => ({\n          getMode,\n          setMode,\n          getData,\n          setData,\n        }),\n        [getMode, setMode, getData, setData]\n      );\n\n      const baseRef = useRef(base);\n\n      useEffect(() => {\n        baseRef.current = base;\n      }, [base]);\n\n      const [readOnlyInternal, setReadOnlyInternal] = useState(false);\n      const [shouldHandleKeyboardEvents, setShouldHandleKeyboardEvents] =\n        useState(true);\n\n      const domContextProperties: DOMContextProperties = useMemo(\n        () => ({\n          canvasRef,\n          handleKeyboardEvent:\n            (keyMap: KeyMap) => (event: React.KeyboardEvent<Element>) => {\n              const platform = getCurrentPlatform(navigator);\n              return handleKeyboardEvent(event.nativeEvent, platform, keyMap);\n            },\n          setReadOnly: setReadOnlyInternal,\n          setShouldHandleKeyboardEvents,\n          getScreenPoint: convertOffsetPoint,\n          getCanvasPoint(input) {\n            return this.convertPoint(this.getScreenPoint(input), \"canvas\");\n          },\n          convertPoint(point, targetCoordinateSystem) {\n            const data = baseRef.current.getData();\n\n            return convertPoint(\n              data.origin,\n              data.zoom,\n              point,\n              targetCoordinateSystem\n            );\n          },\n          setPointerCapture: (pointerId: number) => {\n            canvasRef.current?.setPointerCapture(pointerId);\n          },\n          releasePointerCapture: (pointerId: number) => {\n            canvasRef.current?.releasePointerCapture(pointerId);\n          },\n        }),\n        []\n      );\n\n      const contextProperties = useMemo(\n        (): ContextPropertiesBaseFixType<Mode, Data, ContextProperties> => ({\n          ...base,\n          ...domContextProperties,\n          ...withoutBase(base),\n        }),\n        [base, domContextProperties, withoutBase]\n      );\n\n      const pluginSystemWithPointer = useMemo(\n        () => this.pluginSystem.clone().addPlugin(pointerPlugin()),\n        []\n      );\n\n      const eventHandlers = pluginSystemWithPointer\n        .clone()\n        .getHandlers(contextProperties as any);\n\n      const contextPropertiesRef = useRef(contextProperties);\n\n      useEffect(() => {\n        contextPropertiesRef.current = contextProperties;\n      }, [contextProperties]);\n\n      const handleSizeChange = useCallback((size: Size) => {\n        const { getData, setData } = contextPropertiesRef.current;\n        const data = getData();\n        if (isDeepEqual(size, data.size)) return;\n        setData({ ...data, size });\n      }, []);\n\n      const handleRef = useCallback(\n        (value: HTMLDivElement | null) => {\n          assignRef(canvasRef, value);\n          assignRef(forwardedRef, value);\n        },\n        [forwardedRef]\n      );\n\n      const OwnProvider = this.ReactCanvasProvider;\n\n      return (\n        <HandlerContext.Provider value={contextProperties}>\n          <ModeContext.Provider value={mode}>\n            <DataContext.Provider value={data}>\n              <OwnProvider>\n                <InfiniteCanvasComponent\n                  ref={handleRef}\n                  onChangeSize={handleSizeChange}\n                  readOnly={readOnlyInternal}\n                  shouldHandleKeyboardEvents={shouldHandleKeyboardEvents}\n                  {...rest}\n                  {...eventHandlers}\n                  style={{\n                    cursor: this.pluginSystem.getCursor({ data, mode }),\n                    ...rest.style,\n                  }}\n                >\n                  {children}\n                </InfiniteCanvasComponent>\n              </OwnProvider>\n            </DataContext.Provider>\n          </ModeContext.Provider>\n        </HandlerContext.Provider>\n      );\n    }\n  );\n\n  ReactCanvasProvider = ({ children }: { children: React.ReactNode }) => {\n    return (\n      <ReactCanvasContext.Provider\n        value={this as ReactCanvas<any, any, any, any>}\n      >\n        {children}\n      </ReactCanvasContext.Provider>\n    );\n  };\n\n  createContextProperties = (\n    value: ComponentProps<typeof this.Canvas>[\"contextProperties\"]\n  ) => {\n    return value;\n  };\n\n  getTransform = getCanvasTransform;\n\n  useTransform = () => {\n    const data = this.useData();\n    return useMemo(\n      () => this.getTransform({ origin: data.origin, zoom: data.zoom }),\n      [data.origin, data.zoom]\n    );\n  };\n}\n\nexport const ReactCanvasContext = React.createContext<\n  | ReactCanvas<\n      BaseMode,\n      BaseCanvasData & PointerData,\n      {},\n      ReactEventHandlerMap\n    >\n  | undefined\n>(undefined);\n\nexport const useReactCanvas = () => {\n  const context = useContext(ReactCanvasContext);\n  if (!context) {\n    throw new Error(\"useReactCanvas must be used within a ReactCanvasProvider\");\n  }\n  return context;\n};\n\nexport function createCanvas() {\n  return ReactCanvas.create();\n}\n\nexport type CanvasPluginsToSystem<Plugins extends AnyCanvasPlugin[]> =\n  CanvasPluginsToSystemRecurse<\n    // identity for a union is never\n    never,\n    BaseCanvasData & PointerData,\n    {},\n    ReactEventHandlerMap,\n    Plugins\n  >;\ntype CanvasPluginsToSystemRecurse<\n  Mode extends BaseMode,\n  Data extends BaseCanvasData & PointerData,\n  UniqueContextProperties extends object,\n  EventHandlerMap extends ReactEventHandlerMap,\n  Plugins extends readonly AnyCanvasPlugin[],\n> = Plugins extends readonly [\n  Plugin<infer M, infer D, infer H, infer E>,\n  ...infer Tail extends AnyCanvasPlugin[],\n]\n  ? CanvasPluginsToSystemRecurse<\n      Mode | M,\n      Data & D,\n      // don't include context shared across all plugins\n      UniqueContextProperties & Omit<H, keyof BaseContextProperties<any, any>>,\n      EventHandlerMap & E,\n      Tail\n    >\n  : PluginSystem<\n      Mode,\n      Data,\n      BaseContextProperties<Mode, Data> & UniqueContextProperties,\n      EventHandlerMap\n    >;\n","import { Insets, Size } from \"@noya-app/noya-geometry\";\nimport { KEYBOARD_SHORTCUT_PASSTHROUGH_CLASS } from \"@noya-app/noya-keymap\";\nimport { assignRef, createBeforeInputNormalizer } from \"@noya-app/react-utils\";\nimport React, {\n  CSSProperties,\n  ComponentPropsWithoutRef,\n  ForwardedRef,\n  ReactNode,\n  forwardRef,\n  memo,\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n} from \"react\";\nimport { useAutomaticCanvasSize } from \"../hooks/useAutomaticCanvasSize\";\n\ntype MeasuredChildren = ReactNode | (({ size }: { size: Size }) => ReactNode);\n\nexport interface InfiniteCanvasProps\n  extends Omit<ComponentPropsWithoutRef<\"div\">, \"onBeforeInput\" | \"children\"> {\n  onBeforeInput?: (e: InputEvent) => void;\n  onChangeSize?: (size: Size, insets: Insets) => void;\n  size?: Size;\n  insets?: Insets;\n  autoFocus?: boolean;\n  children: MeasuredChildren;\n  readOnly?: boolean;\n  shouldHandleKeyboardEvents?: boolean;\n  /**\n   * When true, indicates the user is actively editing text.\n   * On touch devices, contentEditable is only enabled when this is true,\n   * to prevent the keyboard from appearing during touch/drag interactions.\n   */\n  isEditingText?: boolean;\n}\n\nexport const InfiniteCanvas = memo(\n  forwardRef(function InfiniteCanvas(\n    {\n      onChangeSize,\n      size,\n      autoFocus = false,\n      style,\n      className: classNameProp,\n      readOnly,\n      onBeforeInput,\n      shouldHandleKeyboardEvents = true,\n      isEditingText,\n      children,\n      ...props\n    }: InfiniteCanvasProps,\n    forwardedRef: ForwardedRef<HTMLDivElement>\n  ) {\n    const containerRef = useRef<HTMLDivElement | null>(null);\n\n    const { canvasSize: measuredSize } = useAutomaticCanvasSize({\n      containerRef,\n      onChangeSize,\n    });\n\n    const normalizer = useMemo(() => {\n      if (!onBeforeInput) return undefined;\n\n      return createBeforeInputNormalizer({\n        onBeforeInput: (e) =>\n          onBeforeInput(\n            new InputEvent(\"beforeinput\", {\n              inputType: e.inputType,\n              data: e.data ?? undefined,\n              dataTransfer: (e.dataTransfer as DataTransfer) ?? undefined,\n            })\n          ),\n      });\n    }, [onBeforeInput]);\n\n    const canvasSize = useMemo(\n      () => size ?? measuredSize,\n      [measuredSize, size]\n    );\n\n    useEffect(() => {\n      const handleBeforeInput = (event: InputEvent) => {\n        // ensure descendant of container\n        const target = event.target as HTMLElement;\n\n        if (!containerRef.current?.contains(target)) return;\n\n        if (normalizer) {\n          normalizer.handleBeforeInput(event);\n        } else {\n          onBeforeInput?.(event);\n        }\n\n        event.preventDefault();\n      };\n\n      if (onBeforeInput && normalizer) {\n        window.addEventListener(\"beforeinput\", handleBeforeInput);\n\n        const handleKeyDown = (event: KeyboardEvent) => {\n          if (!containerRef.current?.contains(event.target as HTMLElement))\n            return;\n\n          const handled = normalizer.handleKeyDownFallback(event);\n          if (handled) event.preventDefault();\n        };\n\n        const handlePaste = (event: ClipboardEvent) => {\n          if (!containerRef.current?.contains(event.target as HTMLElement))\n            return;\n\n          const handled = normalizer.handlePasteFallback(event);\n          if (handled) event.preventDefault();\n        };\n\n        window.addEventListener(\"keydown\", handleKeyDown);\n        window.addEventListener(\"paste\", handlePaste);\n\n        return () => {\n          window.removeEventListener(\"beforeinput\", handleBeforeInput);\n          window.removeEventListener(\"paste\", handlePaste);\n          window.removeEventListener(\"keydown\", handleKeyDown);\n        };\n      }\n    }, [normalizer, onBeforeInput]);\n\n    const className = useMemo(() => {\n      return [\n        classNameProp,\n        shouldHandleKeyboardEvents\n          ? KEYBOARD_SHORTCUT_PASSTHROUGH_CLASS\n          : undefined,\n      ]\n        .filter(Boolean)\n        .join(\" \");\n    }, [classNameProp, shouldHandleKeyboardEvents]);\n\n    // Only enable contentEditable when actively editing text.\n    // This prevents the keyboard from appearing during touch/drag interactions\n    // on mobile, and avoids cursor flickering during pan on desktop.\n    const contentEditable =\n      onBeforeInput && readOnly !== true && isEditingText;\n\n    const childrenElement = useMemo(() => {\n      if (!canvasSize) return null;\n\n      return typeof children === \"function\"\n        ? children({ size: canvasSize })\n        : children;\n    }, [canvasSize, children]);\n\n    return (\n      <div\n        {...props}\n        ref={useCallback(\n          (value: HTMLDivElement | null) => {\n            containerRef.current = value;\n            assignRef(forwardedRef, value);\n          },\n          [forwardedRef]\n        )}\n        contentEditable={contentEditable}\n        suppressContentEditableWarning\n        style={useMemo(\n          (): CSSProperties => ({\n            position: \"relative\",\n            // Prevent browser handling of touch gestures (scroll, zoom)\n            // so the canvas can handle them via JavaScript\n            touchAction: \"none\",\n            ...style,\n          }),\n          [style]\n        )}\n        className={className}\n        tabIndex={0}\n        onFocus={useCallback(() => containerRef.current?.focus(), [])}\n        data-infinite-canvas-root\n      >\n        {onBeforeInput && <Placeholder />}\n        {childrenElement}\n      </div>\n    );\n  })\n);\n\n/**\n * We need a placeholder to be able to handle beforeinput events on the container.\n */\nconst Placeholder = memo(function Placeholder() {\n  return (\n    <span\n      style={{\n        opacity: 0,\n        pointerEvents: \"none\",\n        position: \"absolute\",\n        top: 0,\n        left: -10000,\n        right: 0,\n        bottom: 0,\n      }}\n    >\n      a\n    </span>\n  );\n});\n","import { Insets, Size } from \"@noya-app/noya-geometry\";\nimport { useSize } from \"@noya-app/react-utils\";\nimport { useLayoutEffect, useMemo } from \"react\";\n\ntype CanvasSizes = {\n  // The viewport size is the size of the container element that the user can interact with\n  viewportSize?: Size;\n\n  // The canvas size is the size that actually gets rendered, so it includes the insets\n  canvasSize?: Size;\n};\n\nconst ZERO_INSETS: Insets = {\n  left: 0,\n  right: 0,\n  top: 0,\n  bottom: 0,\n};\n\nexport function useAutomaticCanvasSize({\n  insets = ZERO_INSETS,\n  containerRef,\n  onChangeSize,\n}: {\n  insets?: Insets;\n  containerRef: React.RefObject<HTMLElement | null>;\n  onChangeSize?: (size: Size, insets: Insets) => void;\n}): CanvasSizes {\n  const rawContainerSize = useSize(containerRef);\n\n  const containerSize = useMemo(\n    () =>\n      rawContainerSize\n        ? {\n            width: Math.ceil(Math.max(rawContainerSize.width)),\n            height: Math.ceil(Math.max(rawContainerSize.height)),\n          }\n        : undefined,\n    [rawContainerSize]\n  );\n\n  // Update the canvas size whenever the window is resized\n  useLayoutEffect(() => {\n    if (!containerSize) return;\n\n    onChangeSize?.(containerSize, insets);\n  }, [insets, onChangeSize, containerSize]);\n\n  const canvasSize = useMemo(\n    () =>\n      containerSize && containerSize.width > 0 && containerSize.height > 0\n        ? {\n            width: Math.ceil(containerSize.width + insets.left + insets.right),\n            height: Math.ceil(\n              containerSize.height + insets.top + insets.bottom\n            ),\n          }\n        : undefined,\n    [containerSize, insets.bottom, insets.left, insets.right, insets.top]\n  );\n\n  return {\n    viewportSize: containerSize,\n    canvasSize: canvasSize,\n  };\n}\n","import { AffineTransform, Point, Rect } from \"@noya-app/noya-geometry\";\nimport type { EventWithPointAndTarget } from \"../plugins/contextProperties\";\n\nexport type IdentifiablePoint = Point & { id: string };\n\n// Event coordinates are relative to (0,0), but we want them to include\n// the current page's zoom and offset from the origin\nexport function convertPoint(\n  origin: Point,\n  zoom: number,\n  point: Point,\n  targetCoordinateSystem: \"screen\" | \"canvas\"\n): Point {\n  const transform = AffineTransform.scale(1 / zoom).translate(\n    -origin.x,\n    -origin.y\n  );\n\n  switch (targetCoordinateSystem) {\n    case \"canvas\":\n      return transform.applyTo(point);\n    case \"screen\":\n      return transform.invert().applyTo(point);\n  }\n}\n\nexport function convertOffsetPoint(event: EventWithPointAndTarget): Point {\n  // If the event is not targetting the canvas element, find the ancestor canvas element\n  // by looking for data-infinite-canvas-root attribute\n  const canvas = (event.target as HTMLElement | undefined)?.closest(\n    \"[data-infinite-canvas-root]\"\n  ) as HTMLDivElement;\n\n  if (!canvas) {\n    return { x: 0, y: 0 };\n  }\n\n  const rect = canvas.getBoundingClientRect();\n\n  return {\n    x: event.clientX - rect.left,\n    y: event.clientY - rect.top,\n  };\n}\n\nexport const DEFAULT_POINT_HANDLE_SIZE = 8;\n\n/**\n * Transform points from the coordinate space of the rect to the coordinate space of the canvas.\n */\nexport function getAbsolutizeTransform(rect: Rect): AffineTransform {\n  return AffineTransform.translate(rect.x, rect.y).scale(\n    rect.width,\n    rect.height\n  );\n}\n\n/*\n * Transform points from the coordinate space of the drawn points to the coordinate space of the rect.\n * As a result, all points will be in the range [0, 1].\n */\nexport function getNormalizeTransform(rect: Rect) {\n  const scaleX = rect.width === 0 ? 0 : 1 / rect.width;\n  const scaleY = rect.height === 0 ? 0 : 1 / rect.height;\n  return AffineTransform.scale(scaleX, scaleY).translate(-rect.x, -rect.y);\n}\n","import { isDeepEqual } from \"@noya-app/noya-utils\";\nimport type { CSSProperties } from \"react\";\nimport type { BaseContextProperties } from \"./contextProperties\";\n\nexport type BaseMode = { type: PropertyKey };\n\nexport type BaseEventHandlerMap = Record<PropertyKey, (...args: any[]) => void>;\n\nexport type Plugin<\n  Mode extends BaseMode,\n  Data extends object,\n  ContextProperties extends object,\n  EventHandlerMap extends BaseEventHandlerMap,\n> = {\n  name: string;\n  data: Data;\n  handlers?: (contextProperties: ContextProperties) => Partial<EventHandlerMap>;\n  finalizers?: (\n    contextProperties: ContextProperties\n  ) => Partial<EventHandlerMap>;\n  getCursor?: ({\n    data,\n    mode,\n  }: {\n    data: unknown;\n    mode: unknown;\n  }) => CSSProperties[\"cursor\"] | undefined;\n\n  // Used only for type inference\n  __mode?: Mode;\n};\n\nexport type PluginData<P> =\n  P extends Plugin<any, infer D, any, any> ? D : never;\n\nexport type PluginMode<P> =\n  P extends Plugin<infer M, any, any, any> ? M : never;\n\nexport type PluginContextProperties<P> =\n  P extends Plugin<any, any, infer H, any> ? H : never;\n\nexport type PluginEventHandlerMap<P> =\n  P extends Plugin<any, any, any, infer E> ? E : never;\n\nexport type PluginSystemMode<P> =\n  P extends PluginSystem<infer M, any, any, any> ? M : never;\n\nexport type PluginSystemData<P> =\n  P extends PluginSystem<any, infer D, any, any> ? D : never;\n\nexport type PluginSystemContextProperties<P> =\n  P extends PluginSystem<any, any, infer H, any> ? H : never;\n\nexport type PluginSystemEventHandlerMap<P> =\n  P extends PluginSystem<any, any, any, infer E> ? E : never;\n\nexport type AnyPlugin = Plugin<BaseMode, object, any, BaseEventHandlerMap>;\n\nexport type AnyPluginSystem = PluginSystem<\n  BaseMode,\n  object,\n  any,\n  BaseEventHandlerMap\n>;\n\n/**\n * Ensure that any switch statement over a mode type handles the default case.\n * This helps make sure the system is resilient to new modes being added.\n */\nexport const UnhandledSymbol = Symbol(\"need_to_handle_default_case\");\n\nexport type NoneMode = { type: \"none\" } | { type: typeof UnhandledSymbol };\n\nexport type HandlerMap<\n  ContextProperties extends object,\n  EventHandlerMap extends BaseEventHandlerMap,\n> = {\n  name: string;\n  handlers: (contextProperties: ContextProperties) => Partial<EventHandlerMap>;\n  finalizers: (\n    contextProperties: ContextProperties\n  ) => Partial<EventHandlerMap>;\n};\n\nexport type PluginSystemOptions<ContextProperties extends object> = {\n  debugFilter?: boolean | string | RegExp;\n  debugInfoFromContext?: (context: ContextProperties) => string;\n};\n\nexport type GetCursorUnknown = ({\n  data,\n  mode,\n}: {\n  data: unknown;\n  mode: unknown;\n}) => CSSProperties[\"cursor\"] | undefined;\n\nexport class PluginSystem<\n  Mode extends BaseMode,\n  Data extends object,\n  ContextProperties extends object,\n  EventHandlerMap extends BaseEventHandlerMap,\n> {\n  static create() {\n    return new PluginSystem<NoneMode, {}, {}, {}>({\n      mode: { type: \"none\" },\n      data: {},\n      handlerMaps: [],\n      options: {},\n      getCursor: () => undefined,\n    });\n  }\n\n  mode: Mode;\n  data: Data;\n  handlerMaps: HandlerMap<ContextProperties, EventHandlerMap>[];\n  options: PluginSystemOptions<ContextProperties>;\n  getCursor: GetCursorUnknown;\n\n  constructor({\n    mode,\n    data,\n    handlerMaps,\n    options,\n    getCursor,\n  }: {\n    mode: Mode;\n    data: Data;\n    handlerMaps: HandlerMap<ContextProperties, EventHandlerMap>[];\n    options: PluginSystemOptions<ContextProperties>;\n    getCursor: GetCursorUnknown;\n  }) {\n    this.mode = mode;\n    this.data = data;\n    this.handlerMaps = handlerMaps;\n    this.options = options;\n    this.getCursor = getCursor;\n  }\n\n  get contextProperties(): ContextProperties {\n    throw new Error(\"Handler context is only used for type inference\");\n  }\n\n  debugLog(context: ContextProperties, ...args: any[]) {\n    const debugFilter = this.options.debugFilter;\n\n    if (!debugFilter) return;\n\n    const stringArgs = args.flatMap((arg) => {\n      if (typeof arg === \"string\") return [arg];\n      return [];\n    });\n\n    if (\n      stringArgs.some((arg) => {\n        if (debugFilter instanceof RegExp) {\n          return debugFilter.test(arg);\n        }\n\n        if (typeof debugFilter === \"string\") {\n          return arg.includes(debugFilter);\n        }\n\n        return !!debugFilter;\n      })\n    ) {\n      if (this.options.debugInfoFromContext) {\n        console.info(this.options.debugInfoFromContext(context), ...args);\n      } else {\n        console.info(...args);\n      }\n    }\n  }\n\n  addMode<M extends BaseMode>() {\n    return new PluginSystem<Mode | M, Data, ContextProperties, EventHandlerMap>(\n      {\n        mode: this.mode,\n        data: this.data,\n        handlerMaps: this.handlerMaps,\n        options: this.options,\n        getCursor: this.getCursor,\n      }\n    );\n  }\n\n  addData<D extends object>(data: D) {\n    Object.entries(data).forEach(([k, v]) => {\n      const existingValue = (this.data as Record<string, unknown>)[k];\n\n      if (k in this.data && !isDeepEqual(v, existingValue)) {\n        throw new Error(\n          `Attempted to overwrite existing data key \"${k}\" with a different value`\n        );\n      }\n    });\n\n    return new PluginSystem<Mode, Data & D, ContextProperties, EventHandlerMap>(\n      {\n        mode: this.mode,\n        data: { ...this.data, ...data },\n        handlerMaps: this.handlerMaps,\n        options: this.options,\n        getCursor: this.getCursor,\n      }\n    );\n  }\n\n  addContextProperties<H extends object>() {\n    return new PluginSystem<Mode, Data, ContextProperties & H, EventHandlerMap>(\n      {\n        mode: this.mode,\n        data: this.data,\n        handlerMaps: this.handlerMaps,\n        options: this.options,\n        getCursor: this.getCursor,\n      }\n    );\n  }\n\n  addEventHandlers<E extends BaseEventHandlerMap>(\n    handlerMap?: HandlerMap<ContextProperties, E>\n  ) {\n    type HandlerType = HandlerMap<ContextProperties, EventHandlerMap & E>;\n\n    if (!handlerMap) {\n      return new PluginSystem<\n        Mode,\n        Data,\n        ContextProperties,\n        EventHandlerMap & E\n      >({\n        mode: this.mode,\n        data: this.data,\n        handlerMaps: this.handlerMaps as HandlerType[],\n        options: this.options,\n        getCursor: this.getCursor,\n      });\n    }\n\n    return new PluginSystem<Mode, Data, ContextProperties, EventHandlerMap & E>(\n      {\n        mode: this.mode,\n        data: this.data,\n        handlerMaps: [...this.handlerMaps, handlerMap] as HandlerType[],\n        options: this.options,\n        getCursor: this.getCursor,\n      }\n    );\n  }\n\n  addPlugin<\n    M extends BaseMode,\n    D extends object,\n    H extends object,\n    E extends BaseEventHandlerMap,\n  >(plugin: Plugin<M, D, H, E>) {\n    // TODO: ideally, these should be updated to avoid requiring explicit generic\n    // parameters as well\n    return this.addMode<M>()\n      .addData(plugin.data)\n      .addContextProperties<H>()\n      .addEventHandlers<E>({\n        name: plugin.name,\n        handlers: plugin.handlers || (() => ({})),\n        finalizers: plugin.finalizers || (() => ({})),\n      })\n      .addGetCursor(plugin.getCursor || (() => undefined));\n  }\n\n  addPlugins<Plugins extends AnyPlugin[]>(\n    ...plugins: Plugins\n  ): PluginsToSystem<Plugins>;\n  addPlugins(...plugins: AnyPlugin[]) {\n    return plugins.reduce<AnyPluginSystem>(\n      (system, plugin) => system.addPlugin(plugin),\n      this\n    );\n  }\n\n  addOptions(options: PluginSystemOptions<ContextProperties>) {\n    return new PluginSystem({\n      mode: this.mode,\n      data: this.data,\n      handlerMaps: this.handlerMaps,\n      options,\n      getCursor: this.getCursor,\n    });\n  }\n\n  addGetCursor(getCursor: GetCursorUnknown) {\n    const handleGetCursor = ({ data, mode }: { data: Data; mode: Mode }) => {\n      const cursor = getCursor({ data, mode });\n      if (cursor) return cursor;\n      return this.getCursor({ data, mode });\n    };\n\n    return new PluginSystem({\n      mode: this.mode,\n      data: this.data,\n      handlerMaps: this.handlerMaps,\n      options: this.options,\n      getCursor: handleGetCursor as GetCursorUnknown,\n    });\n  }\n\n  callEventHandler<K extends keyof EventHandlerMap>(\n    context: ContextProperties,\n    key: K,\n    ...args: Parameters<EventHandlerMap[K]>\n  ) {\n    for (const { name, handlers } of this.handlerMaps.toReversed()) {\n      const handlersWithContext = handlers(context);\n\n      if (key in handlersWithContext) {\n        const eventArg = args.length > 0 ? args[0] : undefined;\n\n        if (\n          eventArg &&\n          \"defaultPrevented\" in eventArg &&\n          eventArg.defaultPrevented\n        ) {\n          break;\n        }\n\n        this.debugLog(context, `[${key.toString()}]`, name);\n\n        handlersWithContext[key]?.(...args);\n\n        if (\n          eventArg &&\n          \"defaultPrevented\" in eventArg &&\n          eventArg.defaultPrevented\n        ) {\n          this.debugLog(context, `[${key.toString()}]`, name, \"**handled**\");\n\n          break;\n        }\n      }\n    }\n\n    for (const { name, finalizers } of this.handlerMaps) {\n      const finalizersWithContext = finalizers(context);\n\n      if (key in finalizersWithContext) {\n        this.debugLog(context, `[${key.toString()}]`, name, \"finalizer\");\n\n        finalizersWithContext[key]?.(...args);\n      }\n    }\n  }\n\n  getAllEventNames(context: ContextProperties): (keyof EventHandlerMap)[] {\n    const allKeys = this.handlerMaps.flatMap(({ handlers }) =>\n      Object.keys(handlers(context))\n    );\n\n    return Array.from(new Set(allKeys));\n  }\n\n  getHandlers(context: ContextProperties): Partial<EventHandlerMap> {\n    const handlers = this.handlerMaps.map(({ handlers }) => handlers(context));\n    const allKeys = handlers.flatMap((handlerMap) => Object.keys(handlerMap));\n\n    let result: Partial<EventHandlerMap> = {};\n\n    for (const key of allKeys) {\n      (result[key] as any) = (...args: any[]) => {\n        (this.callEventHandler as any)(context, key, ...args);\n      };\n    }\n\n    return result;\n  }\n\n  clone() {\n    return new PluginSystem({\n      mode: this.mode,\n      data: this.data,\n      handlerMaps: this.handlerMaps,\n      options: this.options,\n      getCursor: this.getCursor,\n    });\n  }\n}\n\nexport type ModeHandlerMap<M extends BaseMode> = {\n  [K in M[\"type\"]]?: (mode: Extract<M, { type: K }>) => void;\n};\n\nexport function modeSwitch<M extends BaseMode, K extends M[\"type\"]>(\n  mode: Extract<M, { type: K }>,\n  handlers: ModeHandlerMap<M>\n) {\n  // The `as any` issue isn't detected in VSCode but is when building.\n  return handlers[mode.type]?.(mode as any);\n}\n\nexport type PluginsToSystem<Plugins extends AnyPlugin[]> =\n  PluginsToSystemRecurse<\n    // identity for a union is never\n    never,\n    {},\n    {},\n    {},\n    Plugins\n  >;\ntype PluginsToSystemRecurse<\n  Mode extends BaseMode,\n  Data extends object,\n  UniqueContextProperties extends object,\n  EventHandlerMap extends BaseEventHandlerMap,\n  Plugins extends readonly AnyPlugin[],\n> = Plugins extends readonly [\n  Plugin<infer M, infer D, infer H, infer E>,\n  ...infer Tail extends AnyPlugin[],\n]\n  ? PluginsToSystemRecurse<\n      Mode | M,\n      Data & D,\n      // don't include context shared across all plugins\n      UniqueContextProperties & Omit<H, keyof BaseContextProperties<any, any>>,\n      EventHandlerMap & E,\n      Tail\n    >\n  : PluginSystem<\n      Mode,\n      Data,\n      BaseContextProperties<Mode, Data> & UniqueContextProperties,\n      EventHandlerMap\n    >;\n","import { distance, Point, Region } from \"@noya-app/noya-geometry\";\nimport { isLeftButtonClicked, isRightButtonClicked } from \"../utils/mouseUtils\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  PointerCaptureProperties,\n  ScreenPointProperties,\n} from \"./contextProperties\";\nimport { NoneMode } from \"./PluginSystem\";\n\ntype PointerMode = NoneMode;\n\nexport type PointerData = {\n  pointer?: Point;\n  pointerDown?: Region;\n  clickCount?: number;\n  lastClickTime?: number;\n  lastClickScreenPoint?: Point;\n  lastRightClickCanvasPoint?: Point;\n  // Non-adjusted pointer position\n  rawPointer?: Point;\n};\n\nexport interface UniquePointerContextProperties {\n  adjustPoint?: (event: React.PointerEvent, point: Point) => Point;\n  completedPointer?: (\n    event: React.PointerEvent,\n    region: Region,\n    clickCount: number\n  ) => void;\n}\n\nexport interface PointerContextProperties\n  extends BaseContextProperties<PointerMode, PointerData>,\n    ScreenPointProperties,\n    PointerCaptureProperties,\n    UniquePointerContextProperties {}\n\ntype PointerPluginOptions = {\n  clickTimeThreshold?: number;\n};\n\nexport function pointerPlugin(options: PointerPluginOptions = {}) {\n  const { clickTimeThreshold = 300 } = options;\n\n  return createCanvasPlugin({\n    name: \"pointer\",\n    data: { clickCount: 0, lastClickTime: 0 },\n    handlers: ({\n      getMode,\n      setMode,\n      getData,\n      setData,\n      adjustPoint = (_, point) => point,\n      ...context\n    }: PointerContextProperties) => ({\n      onPointerDown(event) {\n        const data = getData();\n\n        if (isRightButtonClicked(event)) {\n          setData({\n            ...data,\n            lastRightClickCanvasPoint: context.getCanvasPoint(\n              event.nativeEvent\n            ),\n          });\n          return;\n        }\n\n        if (!isLeftButtonClicked(event)) return;\n\n        const screenPoint = context.getScreenPoint(event.nativeEvent);\n        const rawEnd = context.getCanvasPoint(event.nativeEvent);\n        const end = adjustPoint(event, rawEnd);\n\n        const currentTime = Date.now();\n        let clickCount = data.clickCount ?? 0;\n\n        if (\n          currentTime - (data.lastClickTime ?? 0) < clickTimeThreshold &&\n          data.lastClickScreenPoint &&\n          distance(data.lastClickScreenPoint, screenPoint) < 2\n        ) {\n          clickCount += 1;\n        } else {\n          clickCount = 1;\n        }\n\n        setData({\n          ...data,\n          pointerDown: { anchor: end, head: end },\n          pointer: end,\n          rawPointer: rawEnd,\n          clickCount,\n          lastClickTime: currentTime,\n          lastClickScreenPoint: screenPoint,\n        });\n\n        context.setPointerCapture(event.pointerId);\n      },\n      onPointerMove(event) {\n        const data = getData();\n\n        const rawEnd = context.getCanvasPoint(event.nativeEvent);\n        const end = adjustPoint(event, rawEnd);\n\n        if (data.pointerDown) {\n          setData({\n            ...data,\n            pointerDown: { ...data.pointerDown, head: end },\n            pointer: end,\n            rawPointer: rawEnd,\n          });\n        } else {\n          setData({ ...data, pointer: end, rawPointer: rawEnd });\n        }\n      },\n      onPointerUp(event) {\n        if (!isLeftButtonClicked(event)) return;\n\n        const data = getData();\n\n        const rawEnd = context.getCanvasPoint(event.nativeEvent);\n        const end = adjustPoint(event, rawEnd);\n\n        if (data.pointerDown) {\n          setData({\n            ...data,\n            pointerDown: { ...data.pointerDown, head: end },\n            rawPointer: rawEnd,\n          });\n\n          context.completedPointer?.(\n            event,\n            { ...data.pointerDown, head: end },\n            data.clickCount ?? 0\n          );\n\n          context.releasePointerCapture(event.pointerId);\n        } else {\n          setData({ ...data, pointer: end, rawPointer: rawEnd });\n        }\n      },\n      onPointerLeave() {\n        const data = getData();\n\n        setData({ ...data, pointer: undefined, rawPointer: undefined });\n      },\n      onPointerCancel() {\n        const data = getData();\n\n        setData({\n          ...data,\n          pointerDown: undefined,\n          pointer: undefined,\n          rawPointer: undefined,\n        });\n      },\n    }),\n    finalizers: (context) => ({\n      onPointerUp() {\n        const data = context.getData();\n\n        if (!data.pointerDown) return;\n\n        context.setData({\n          ...data,\n          pointerDown: undefined,\n          rawPointer: undefined,\n        });\n      },\n    }),\n  });\n}\n","export function isLeftButtonClicked(event: React.MouseEvent) {\n  return event.button === 0;\n}\n\nexport function isRightButtonClicked(event: React.MouseEvent) {\n  return event.button === 2;\n}\n","import {\n  CompassDirection,\n  Point,\n  Rect,\n  compassDirections,\n  getCompassDirectionAnchor,\n} from \"@noya-app/noya-geometry\";\nimport { PointData } from \"../plugins/pointPlugin\";\nimport { ScaleData } from \"../plugins/scalePlugin\";\nimport { IdentifiablePoint } from \"./pointUtils\";\n\nexport type DragHandle = {\n  rect: Rect;\n  compassDirection: CompassDirection;\n  offset: Point;\n  strokeWidth: number;\n};\n\nexport function getDragHandles({\n  selectionRect,\n  data: { zoom, dragHandleSize },\n}: {\n  selectionRect: Rect;\n  data: Pick<ScaleData, \"zoom\" | \"dragHandleSize\">;\n}): DragHandle[] {\n  const handleSize = dragHandleSize / zoom;\n\n  return compassDirections.map((compassDirection) => {\n    const anchor = getCompassDirectionAnchor(compassDirection, selectionRect);\n\n    return {\n      rect: {\n        x: anchor.x - handleSize / 2,\n        y: anchor.y - handleSize / 2,\n        width: handleSize,\n        height: handleSize,\n      },\n      compassDirection,\n      offset: anchor,\n      strokeWidth: 1 / zoom,\n    };\n  });\n}\n\ntype PointHandle = {\n  rect: Rect;\n  strokeWidth: number;\n  id: string;\n};\n\nexport function getPointHandles({\n  points,\n  data: { zoom, pointHandleSize },\n}: {\n  points: IdentifiablePoint[];\n  data: Pick<PointData, \"zoom\" | \"pointHandleSize\">;\n}): PointHandle[] {\n  const handleSize = pointHandleSize / zoom;\n\n  return points.map((point) => {\n    return {\n      rect: {\n        x: point.x - handleSize / 2,\n        y: point.y - handleSize / 2,\n        width: handleSize,\n        height: handleSize,\n      },\n      strokeWidth: 1 / zoom,\n      id: point.id,\n    };\n  });\n}\n","import { Point } from \"@noya-app/noya-geometry\";\nimport { Group, Polyline, Rectangle } from \"@noya-app/noya-graphics\";\nimport React, { useMemo } from \"react\";\nimport { BaseCanvasData, getCanvasTransform } from \"../plugins/baseCanvas\";\nimport {\n  GradientEditorData,\n  GradientEditorGradient,\n  GradientEditorMode,\n  useGradientEditor,\n} from \"../plugins/gradientEditorPlugin\";\n\nconst ACTIVE_COLOR = \"#FFA500\";\nconst DEFAULT_BORDER_COLOR = \"#FFFFFF\";\n\nexport function GradientHandles({\n  gradient,\n  data,\n  mode,\n}: {\n  gradient?: GradientEditorGradient;\n  data?: GradientEditorData & Pick<BaseCanvasData, \"origin\" | \"zoom\">;\n  mode?: GradientEditorMode<unknown>;\n}) {\n  const gradientState = useGradientEditor();\n\n  gradient = gradient ?? gradientState.gradient;\n  data = data ?? gradientState.data;\n  mode = mode ?? gradientState.mode;\n\n  const transform = useMemo(() => getCanvasTransform(data), [data]);\n\n  if (!gradient || gradient.stops.length < 2) return null;\n\n  const start = gradient.stops.find((stop) => stop.type === \"start\");\n  const end = gradient.stops.find((stop) => stop.type === \"end\");\n\n  if (!start || !end) return null;\n\n  const lineStrokeWidth = 1 / data.zoom;\n\n  const getHandleRect = (point: Point) => {\n    const size = data.handleSize / data.zoom;\n    return {\n      x: point.x - size / 2,\n      y: point.y - size / 2,\n      width: size,\n      height: size,\n    };\n  };\n\n  return (\n    <Group transform={transform}>\n      <Polyline\n        points={[start.point, end.point]}\n        paint={{\n          style: \"stroke\",\n          strokeWidth: lineStrokeWidth,\n          color: \"#FFFFFF\",\n        }}\n      />\n      {gradient.stops.map((stop) => {\n        const rect = getHandleRect(stop.point);\n\n        const isActive =\n          mode?.type === \"draggingGradientStop\" && mode.stopId === stop.id;\n        const isHovered = data.hoveredStopId === stop.id;\n\n        return (\n          <React.Fragment key={stop.id}>\n            <Rectangle\n              rect={rect}\n              cornerRadius={rect.width / 2}\n              paint={{\n                style: \"fill\",\n                color: stop.color ?? \"#FFFFFF\",\n              }}\n            />\n            <Rectangle\n              rect={rect}\n              cornerRadius={rect.width / 2}\n              paint={{\n                style: \"stroke\",\n                strokeWidth: lineStrokeWidth,\n                color:\n                  isActive || isHovered ? ACTIVE_COLOR : DEFAULT_BORDER_COLOR,\n              }}\n            />\n          </React.Fragment>\n        );\n      })}\n    </Group>\n  );\n}\n","import {\n  Point,\n  projectPointOntoLine,\n  Rect,\n  rectContainsPoint,\n} from \"@noya-app/noya-geometry\";\nimport { isMoving } from \"../utils/isMoving\";\nimport { BaseCanvasData, createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  ScreenPointProperties,\n} from \"./contextProperties\";\nimport { modeSwitch, NoneMode } from \"./PluginSystem\";\nimport { PointerData } from \"./pointerPlugin\";\nimport { useReactCanvas } from \"./ReactCanvas\";\n\nexport const DEFAULT_GRADIENT_HANDLE_SIZE = 12;\nexport const GRADIENT_EDITOR_SURFACE_ATTRIBUTE = \"data-gradient-editor-surface\";\n\nexport type GradientStopHandle = {\n  id: string;\n  index: number;\n  type: \"start\" | \"end\" | \"stop\";\n  position: number;\n  point: Point;\n  color?: string;\n};\n\nexport type GradientEditorGradient = {\n  rect: Rect;\n  stops: GradientStopHandle[];\n};\n\nexport type GradientEditorMode<StateSnapshot> =\n  | NoneMode\n  | {\n      type: \"draggingGradientStop\";\n      stopId: string;\n      snapshot: StateSnapshot;\n    };\n\nexport type GradientEditorData = {\n  handleSize: number;\n  hoveredStopId?: string;\n  activeStopId?: string;\n  zoom: number;\n} & Pick<PointerData, \"pointer\" | \"pointerDown\">;\n\nexport interface GradientEditorContextProperties<StateSnapshot>\n  extends BaseContextProperties<\n      GradientEditorMode<StateSnapshot>,\n      GradientEditorData\n    >,\n    ScreenPointProperties {\n  canEditGradient: () => boolean;\n  getGradient: () => GradientEditorGradient | undefined;\n  getStateSnapshot: () => StateSnapshot;\n  moveStop: (parameters: {\n    id: string;\n    point: Point;\n    position: number;\n    snapshot: StateSnapshot;\n  }) => void;\n}\n\nexport type GradientEditorPluginOptions = {\n  handleSize?: number;\n  movementThreshold?: number;\n};\n\nfunction clamp01(value: number) {\n  return Math.min(Math.max(value, 0), 1);\n}\n\nfunction getHandleRect(\n  stop: GradientStopHandle,\n  data: Pick<GradientEditorData, \"handleSize\" | \"zoom\">\n): Rect {\n  const size = data.handleSize / data.zoom;\n\n  return {\n    x: stop.point.x - size / 2,\n    y: stop.point.y - size / 2,\n    width: size,\n    height: size,\n  };\n}\n\nfunction findStopAtPoint({\n  point,\n  gradient,\n  data,\n}: {\n  point: Point;\n  gradient: GradientEditorGradient;\n  data: GradientEditorData;\n}) {\n  return gradient.stops.find((stop) =>\n    rectContainsPoint(getHandleRect(stop, data), point)\n  );\n}\n\nexport function gradientEditorPlugin<StateSnapshot>(\n  options: GradientEditorPluginOptions = {}\n) {\n  const { handleSize = DEFAULT_GRADIENT_HANDLE_SIZE, movementThreshold = 0 } =\n    options;\n\n  return createCanvasPlugin({\n    name: \"gradientEditor\",\n    data: {\n      handleSize,\n      hoveredStopId: undefined,\n      activeStopId: undefined,\n      zoom: 1,\n    },\n    handlers: (context: GradientEditorContextProperties<StateSnapshot>) => ({\n      onPointerDown(event) {\n        const canEditGradient = context.canEditGradient();\n\n        if (!canEditGradient) return;\n\n        if (context.getMode().type !== \"none\") return;\n\n        const data = context.getData();\n        const pointerDown = data.pointerDown;\n\n        if (!pointerDown) return;\n\n        const gradient = context.getGradient();\n\n        if (!gradient) return;\n\n        const stop = findStopAtPoint({\n          point: pointerDown.anchor,\n          gradient,\n          data,\n        });\n\n        if (!stop) return;\n\n        context.setMode({\n          type: \"draggingGradientStop\",\n          stopId: stop.id,\n          snapshot: context.getStateSnapshot(),\n        });\n\n        context.setData((current) => ({\n          ...current,\n          activeStopId: stop.id,\n        }));\n\n        event.preventDefault();\n      },\n      onPointerMove(event) {\n        const canEditGradient = context.canEditGradient();\n\n        if (!canEditGradient) return;\n\n        const data = context.getData();\n        const gradient = context.getGradient();\n\n        if (!gradient) {\n          if (data.hoveredStopId) {\n            context.setData((current) => ({\n              ...current,\n              hoveredStopId: undefined,\n            }));\n          }\n\n          return;\n        }\n\n        modeSwitch(context.getMode(), {\n          none: () => {\n            if (data.pointerDown) return;\n\n            const pointer = data.pointer;\n            const hoveredStop = pointer\n              ? findStopAtPoint({ point: pointer, gradient, data })\n              : undefined;\n\n            if (hoveredStop?.id !== data.hoveredStopId) {\n              context.setData((current) => ({\n                ...current,\n                hoveredStopId: hoveredStop?.id,\n              }));\n            }\n          },\n          draggingGradientStop: (mode) => {\n            const pointerDown = data.pointerDown;\n\n            if (!pointerDown) return;\n\n            if (\n              !isMoving(\n                pointerDown.anchor,\n                pointerDown.head,\n                data.zoom,\n                movementThreshold\n              )\n            ) {\n              return;\n            }\n\n            const stop = gradient.stops.find(\n              (candidate) => candidate.id === mode.stopId\n            );\n\n            const start = gradient.stops.find(\n              (candidate) => candidate.type === \"start\"\n            );\n            const end = gradient.stops.find(\n              (candidate) => candidate.type === \"end\"\n            );\n\n            if (!stop || !start || !end) return;\n\n            let nextPoint = pointerDown.head;\n            let nextPosition = stop.position;\n\n            if (stop.type === \"stop\") {\n              const projection = projectPointOntoLine(pointerDown.head, [\n                start.point,\n                end.point,\n              ]);\n\n              nextPoint = projection.projected;\n              nextPosition = projection.t;\n            } else if (stop.type === \"start\") {\n              nextPosition = 0;\n            } else if (stop.type === \"end\") {\n              nextPosition = 1;\n            }\n\n            context.moveStop({\n              id: stop.id,\n              point: nextPoint,\n              position: clamp01(nextPosition),\n              snapshot: mode.snapshot,\n            });\n\n            event.preventDefault();\n          },\n        });\n      },\n      onPointerUp(event) {\n        const canEditGradient = context.canEditGradient();\n\n        if (!canEditGradient) return;\n\n        modeSwitch(context.getMode(), {\n          draggingGradientStop: () => {\n            context.setMode({ type: \"none\" });\n            context.setData((current) => ({\n              ...current,\n              activeStopId: undefined,\n            }));\n            event.preventDefault();\n          },\n        });\n      },\n      onPointerLeave() {\n        if (context.getMode().type !== \"none\") return;\n\n        const data = context.getData();\n\n        if (data.hoveredStopId) {\n          context.setData((current) => ({\n            ...current,\n            hoveredStopId: undefined,\n          }));\n        }\n      },\n      onPointerCancel() {\n        context.setMode({ type: \"none\" });\n        context.setData((current) => ({\n          ...current,\n          activeStopId: undefined,\n          hoveredStopId: undefined,\n        }));\n      },\n    }),\n    getCursor: ({ data }) => {\n      if (data.activeStopId || data.hoveredStopId) {\n        return \"pointer\";\n      }\n\n      return undefined;\n    },\n  });\n}\n\nexport function useGradientEditor() {\n  const ReactCanvas = useReactCanvas();\n  const data = ReactCanvas.useData() as GradientEditorData & BaseCanvasData;\n  const mode = ReactCanvas.useMode() as GradientEditorMode<unknown>;\n  const context = ReactCanvas.useContextPropertiesRef() as {\n    getGradient?: () => GradientEditorGradient | undefined;\n  };\n\n  const gradient = context.getGradient?.();\n\n  return { data, mode, gradient };\n}\n","import { Point, distance } from \"@noya-app/noya-geometry\";\n\nexport const DEFAULT_MOVEMENT_THRESHOLD = 2;\n\nexport function isMoving(\n  current: Point,\n  origin: Point,\n  zoomValue: number,\n  threshold: number\n): boolean {\n  threshold = threshold / zoomValue;\n\n  return distance(current, origin) >= threshold;\n}\n","import { createRect, insetRect } from \"@noya-app/noya-geometry\";\n\nimport { Rectangle } from \"@noya-app/noya-graphics\";\nimport React, { useMemo } from \"react\";\nimport { BaseCanvasData, getCanvasTransform } from \"../plugins/baseCanvas\";\nimport { isMarqueeMode } from \"../plugins/marqueePlugin\";\nimport { BaseMode } from \"../plugins/PluginSystem\";\nimport { useReactCanvas } from \"../plugins/ReactCanvas\";\n\nexport function Marquee({\n  data,\n  mode,\n}: {\n  data?: Pick<BaseCanvasData, \"zoom\" | \"origin\">;\n  mode?: BaseMode;\n}) {\n  const ReactCanvas = useReactCanvas();\n  const canvasData = ReactCanvas.useData();\n  const canvasMode = ReactCanvas.useMode();\n\n  data = data ?? canvasData;\n  mode = mode ?? canvasMode;\n\n  const transform = useMemo(() => getCanvasTransform(data), [data]);\n\n  if (!isMarqueeMode(mode)) return null;\n\n  return (\n    <Rectangle\n      rect={transform.applyTo(insetRect(createRect(mode.region), 0.5))}\n      paint={{\n        style: \"stroke\",\n        color: \"#FFA500\",\n        strokeWidth: 1,\n      }}\n    />\n  );\n}\n","import { Region, createRect } from \"@noya-app/noya-geometry\";\nimport { DEFAULT_MOVEMENT_THRESHOLD, isMoving } from \"../utils/isMoving\";\nimport { makeSelection } from \"../utils/selectionUtils\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  ElementProperties,\n  SelectableProperties,\n} from \"./contextProperties\";\nimport { BaseMode, NoneMode, modeSwitch } from \"./PluginSystem\";\nimport { PointerData } from \"./pointerPlugin\";\n\nexport type MarqueeMode = {\n  type: \"marquee\";\n  region: Region;\n  selectedElementIdsSnapshot: string[];\n};\n\nexport function isMarqueeMode(mode: BaseMode): mode is MarqueeMode {\n  return mode.type === \"marquee\";\n}\n\nexport type MarqueePluginMode = NoneMode | MarqueeMode;\n\nexport type MarqueeData = {\n  selectedElementIds: string[];\n  zoom: number;\n} & Pick<PointerData, \"pointerDown\">;\n\nexport interface MarqueeHandlerContext<CanvasElement>\n  extends BaseContextProperties<MarqueePluginMode, MarqueeData>,\n    ElementProperties<CanvasElement>,\n    SelectableProperties<CanvasElement> {\n  adjustMarqueeRegion?: (event: React.PointerEvent, region: Region) => Region;\n}\n\nexport type MarqueePluginOptions = {\n  movementThreshold?: number;\n};\n\nexport function marqueePlugin<CanvasElement>(\n  options: MarqueePluginOptions = {}\n) {\n  const { movementThreshold = DEFAULT_MOVEMENT_THRESHOLD } = options;\n\n  return createCanvasPlugin({\n    name: \"marquee\",\n    data: {\n      selectedElementIds: [],\n      zoom: 1,\n    },\n    handlers: ({\n      getMode,\n      setMode,\n      getData,\n      setData,\n      adjustMarqueeRegion = (_, region) => region,\n      ...context\n    }: MarqueeHandlerContext<CanvasElement>) => ({\n      onPointerMove(event) {\n        modeSwitch(getMode(), {\n          none: () => {\n            const data = getData();\n\n            if (!data.pointerDown) return;\n\n            if (\n              isMoving(\n                data.pointerDown.anchor,\n                data.pointerDown.head,\n                data.zoom,\n                movementThreshold\n              )\n            ) {\n              setMode({\n                type: \"marquee\",\n                region: adjustMarqueeRegion(event, data.pointerDown),\n                selectedElementIdsSnapshot: data.selectedElementIds,\n              });\n\n              event.preventDefault();\n            }\n          },\n          marquee: ({ selectedElementIdsSnapshot }) => {\n            const data = getData();\n\n            if (!data.pointerDown) return;\n\n            const region = adjustMarqueeRegion(event, data.pointerDown);\n\n            const elements = context.filterElements({\n              at: createRect(region),\n              predicate: context.isSelectable,\n            });\n\n            setData({\n              ...data,\n              selectedElementIds: elements.map((element) =>\n                context.getElementId(element)\n              ),\n            });\n\n            setMode({\n              type: \"marquee\",\n              region,\n              selectedElementIdsSnapshot,\n            });\n\n            event.preventDefault();\n          },\n        });\n      },\n      onPointerUp(event) {\n        modeSwitch(getMode(), {\n          marquee: ({ selectedElementIdsSnapshot }) => {\n            const data = getData();\n\n            if (!data.pointerDown) return;\n\n            const region = adjustMarqueeRegion(event, data.pointerDown);\n\n            // If not a move, select elements at the start point\n            if (\n              !isMoving(\n                data.pointerDown.anchor,\n                data.pointerDown.head,\n                data.zoom,\n                movementThreshold\n              )\n            ) {\n              const elements = context.filterElements({\n                at: region.anchor,\n                predicate: context.isSelectable,\n              });\n\n              setData({\n                ...data,\n                selectedElementIds: makeSelection(\n                  selectedElementIdsSnapshot,\n                  elements.length > 0\n                    ? [context.getElementId(elements[0])]\n                    : [],\n                  \"symmetricDifference\"\n                ),\n              });\n            } else {\n              const elements = context.filterElements({\n                at: createRect(region),\n                predicate: context.isSelectable,\n              });\n\n              setData({\n                ...data,\n                selectedElementIds: elements.map((element) =>\n                  context.getElementId(element)\n                ),\n              });\n            }\n\n            setMode({ type: \"none\" });\n\n            event.preventDefault();\n          },\n        });\n      },\n    }),\n  });\n}\n","export type SelectionType =\n  | \"replace\"\n  | \"intersection\"\n  | \"difference\"\n  | \"symmetricDifference\";\n\nexport function updateSelection<T extends string | number>(\n  currentIds: T[],\n  newIds: T | T[] | undefined,\n  selectionType: SelectionType\n) {\n  const ids =\n    newIds === undefined ? [] : Array.isArray(newIds) ? newIds : [newIds];\n\n  switch (selectionType) {\n    case \"intersection\":\n      currentIds.push(...ids.filter((id) => !currentIds.includes(id)));\n      return;\n    case \"difference\":\n      ids.forEach((id) => {\n        const selectedIndex = currentIds.indexOf(id);\n        currentIds.splice(selectedIndex, 1);\n      });\n      return;\n    case \"replace\":\n      // Update currentIds array in-place\n      currentIds.length = 0;\n      currentIds.push(...ids);\n      return;\n    case \"symmetricDifference\":\n      ids.forEach((id) => {\n        const selectedIndex = currentIds.indexOf(id);\n        if (selectedIndex === -1) {\n          currentIds.push(id);\n        } else {\n          currentIds.splice(selectedIndex, 1);\n        }\n      });\n      return;\n  }\n}\n\nexport function makeSelection(\n  a: string[],\n  b: string[],\n  selectionType: SelectionType\n): string[] {\n  const selection = [...a];\n  updateSelection(selection, b, selectionType);\n  return selection;\n}\n\nexport function updateSelectionWithItem(\n  selection: string[],\n  elementId: string | undefined,\n  shiftKey: boolean\n) {\n  if (elementId) {\n    if (selection.includes(elementId)) {\n      if (shiftKey && selection.length !== 1) {\n        return makeSelection(selection, [elementId], \"difference\");\n      } else {\n        return selection;\n      }\n    } else {\n      return makeSelection(\n        selection,\n        [elementId],\n        shiftKey ? \"intersection\" : \"replace\"\n      );\n    }\n  } else {\n    return [];\n  }\n}\n","import { insetRect, Rect } from \"@noya-app/noya-geometry\";\nimport { Group, Rectangle } from \"@noya-app/noya-graphics\";\nimport React, { useMemo } from \"react\";\nimport { BaseCanvasData, getCanvasTransform } from \"../plugins/baseCanvas\";\nimport { PointData } from \"../plugins/pointPlugin\";\nimport { useReactCanvas } from \"../plugins/ReactCanvas\";\nimport { ScaleData } from \"../plugins/scalePlugin\";\nimport { getPointHandles } from \"../utils/dragHandleUtils\";\nimport { getAbsolutizeTransform, IdentifiablePoint } from \"../utils/pointUtils\";\n\nexport function PointHandles({\n  points,\n  data,\n}: {\n  points: {\n    point: IdentifiablePoint;\n    pathRect: Rect;\n  }[];\n  data?: Pick<BaseCanvasData, \"zoom\" | \"origin\"> &\n    Pick<ScaleData, \"dragHandleSize\"> &\n    PointData;\n}) {\n  const ReactCanvas = useReactCanvas();\n  const canvasData = ReactCanvas.useData() as ScaleData &\n    BaseCanvasData &\n    PointData;\n\n  data = data ?? canvasData;\n\n  const transform = useMemo(() => getCanvasTransform(data), [data]);\n  const pointIds = useMemo(\n    () => points.map((point) => point.point.id),\n    [points]\n  );\n\n  const dragHandles = useMemo(() => {\n    const pointHandles = getPointHandles({\n      points: points.map((point) =>\n        getAbsolutizeTransform(point.pathRect).applyTo(point.point)\n      ),\n      data: { zoom: data.zoom, pointHandleSize: data.pointHandleSize },\n    });\n    return pointHandles.filter((handle) => pointIds.includes(handle.id));\n  }, [points, data.zoom, data.pointHandleSize, pointIds]);\n\n  return (\n    <Group transform={transform}>\n      {dragHandles.map((handle, i) => {\n        const inset = 0.5 / data.zoom;\n        const rect = insetRect(handle.rect, inset);\n\n        return (\n          <React.Fragment key={i}>\n            <Rectangle\n              rect={rect}\n              paint={{\n                style: \"fill\",\n                color: \"#FFFFFF\",\n              }}\n              cornerRadius={data.pointHandleSize / 2}\n            />\n            <Rectangle\n              rect={rect}\n              paint={{\n                style: \"stroke\",\n                strokeWidth: handle.strokeWidth,\n                color:\n                  data.highlightedPointId === handle.id ? \"#FFA500\" : \"#1E90FF\",\n              }}\n              cornerRadius={data.pointHandleSize / 2}\n            />\n          </React.Fragment>\n        );\n      })}\n    </Group>\n  );\n}\n","import { insetRect, Rect } from \"@noya-app/noya-geometry\";\nimport { Rectangle } from \"@noya-app/noya-graphics\";\nimport React, { useMemo } from \"react\";\nimport { BaseCanvasData, getCanvasTransform } from \"../plugins/baseCanvas\";\nimport { useReactCanvas } from \"../plugins/ReactCanvas\";\n\nexport function SelectionRect({\n  selectionRect,\n  borderRadius = 0,\n  data,\n}: {\n  selectionRect?: Rect;\n  borderRadius?: number;\n  data?: Pick<BaseCanvasData, \"zoom\" | \"origin\">;\n}) {\n  const ReactCanvas = useReactCanvas();\n  const canvasData = ReactCanvas.useData();\n\n  data = data ?? canvasData;\n\n  const transform = useMemo(() => getCanvasTransform(data), [data]);\n\n  if (!selectionRect) return null;\n\n  return (\n    <Rectangle\n      cornerRadius={borderRadius}\n      rect={transform.applyTo(insetRect(selectionRect, 0.5))}\n      paint={{\n        style: \"stroke\",\n        color: \"#1E90FF\",\n      }}\n    />\n  );\n}\n","import { Polyline } from \"@noya-app/noya-graphics\";\nimport React from \"react\";\nimport { BaseCanvasData } from \"../plugins/baseCanvas\";\nimport { useReactCanvas } from \"../plugins/ReactCanvas\";\nimport { SnapLine } from \"../utils/snapUtils\";\n\ntype SnapLinesProps = {\n  lines: SnapLine[];\n  color?: string;\n  data?: Pick<BaseCanvasData, \"zoom\">;\n};\n\nexport const SnapLines: React.FC<SnapLinesProps> = ({\n  lines,\n  color = \"#FFA500\",\n  data,\n}) => {\n  const ReactCanvas = useReactCanvas();\n  const canvasData = ReactCanvas.useData();\n\n  data = data ?? canvasData;\n\n  const zoom = data.zoom;\n  const strokeWidth = 2 / zoom;\n\n  return (\n    <>\n      {lines.map((line, index) => (\n        <Polyline\n          key={index}\n          points={[\n            { x: line.x1, y: line.y1 },\n            { x: line.x2, y: line.y2 },\n          ]}\n          paint={{\n            style: \"stroke\",\n            strokeWidth,\n            color,\n          }}\n        />\n      ))}\n    </>\n  );\n};\n","import { distance, Point } from '@noya-app/noya-geometry';\nimport { useCallback, useRef } from 'react';\n\nexport function useMultipleClickCount() {\n  const lastClick = useRef<\n    | {\n        timestamp: number;\n        point: Point;\n        clickCount: number;\n      }\n    | undefined\n  >(undefined);\n\n  const setLatestClick = useCallback(\n    (point: Point) => {\n      const timestamp = Date.now();\n      const clickCount =\n        lastClick.current &&\n        distance(lastClick.current.point, point) < 5 &&\n        timestamp - lastClick.current.timestamp < 300\n          ? lastClick.current.clickCount + 1\n          : 1;\n\n      lastClick.current = { point, timestamp, clickCount };\n\n      return clickCount;\n    },\n    [lastClick],\n  );\n\n  const getClickCount = useCallback(() => {\n    return lastClick.current ? lastClick.current.clickCount : 1;\n  }, [lastClick]);\n\n  return {\n    getClickCount,\n    setLatestClick,\n  };\n}\n","import { rectContainsPoint } from \"@noya-app/noya-geometry\";\nimport {\n  BaseContextProperties,\n  createCanvasPlugin,\n  NoneMode,\n  PointerData,\n} from \"@noya-app/noya-infinite-canvas\";\n\ntype BaseDOMElementRef = {\n  getBoundingClientRect: () => DOMRect;\n};\n\ntype DOMEventMode<DOMElementRef> =\n  | NoneMode\n  | { type: \"domPointerDown\"; element: DomElementAtPoint<DOMElementRef> };\n\ntype DOMEventData<DOMElementRef> = {\n  domElementRefs: Record<string, React.RefObject<DOMElementRef | null>>;\n  hoveredDomElementId: string | undefined;\n} & Pick<PointerData, \"pointerDown\">;\n\ninterface DOMEventContextProperties<DOMElementRef>\n  extends BaseContextProperties<\n    DOMEventMode<DOMElementRef>,\n    DOMEventData<DOMElementRef>\n  > {\n  onClickDomElement?: (\n    event: React.MouseEvent,\n    options: {\n      id: string;\n      ref?: React.RefObject<DOMElementRef | null>;\n    }\n  ) => void;\n}\n\nexport function domEventPlugin<DOMElementRef extends BaseDOMElementRef>() {\n  return createCanvasPlugin({\n    name: \"domEvent\",\n    data: {\n      domElementRefs: {},\n      hoveredDomElementId: undefined,\n    },\n    handlers: (context: DOMEventContextProperties<DOMElementRef>) => ({\n      onPointerMove(event) {\n        const data = context.getData();\n\n        const hoveredDomElement = getDomElementAtPoint(data, event);\n        if (hoveredDomElement?.id !== data.hoveredDomElementId) {\n          context.setData({\n            ...data,\n            hoveredDomElementId: hoveredDomElement?.id,\n          });\n        }\n      },\n      onPointerDown(event) {\n        if (!context.onClickDomElement) return;\n\n        const data = context.getData();\n        const clickedDomElement = getDomElementAtPoint(data, event);\n\n        if (clickedDomElement) {\n          context.setMode({\n            type: \"domPointerDown\",\n            element: clickedDomElement,\n          });\n\n          event.preventDefault();\n          event.stopPropagation();\n        }\n      },\n      onPointerUp(event) {\n        const mode = context.getMode();\n\n        if (mode.type !== \"domPointerDown\") return;\n\n        const data = context.getData();\n        const clickedDomElement = getDomElementAtPoint(data, event);\n\n        if (clickedDomElement?.id !== mode.element.id) return;\n\n        context.onClickDomElement?.(event, mode.element);\n        context.setMode({ type: \"none\" });\n      },\n      onPointerLeave() {\n        const mode = context.getMode();\n\n        if (mode.type !== \"none\") return;\n\n        const data = context.getData();\n\n        if (data.hoveredDomElementId) {\n          context.setData((data) => ({\n            ...data,\n            hoveredDomElementId: undefined,\n          }));\n        }\n      },\n    }),\n  });\n}\n\ntype DomElementAtPoint<DOMElementRef> = {\n  id: string;\n  ref: React.RefObject<DOMElementRef | null>;\n};\n\nfunction getDomElementAtPoint<DOMElementRef extends BaseDOMElementRef>(\n  data: DOMEventData<DOMElementRef>,\n  event: React.PointerEvent\n): DomElementAtPoint<DOMElementRef> | undefined {\n  const pointer = { x: event.clientX, y: event.clientY };\n  const hoveredDomElement = Object.entries(data.domElementRefs).find(\n    ([_, ref]) => {\n      if (!ref.current) return false;\n      const rect = ref.current.getBoundingClientRect();\n      return rectContainsPoint(rect, pointer);\n    }\n  );\n  return hoveredDomElement\n    ? {\n        id: hoveredDomElement[0],\n        ref: hoveredDomElement[1],\n      }\n    : undefined;\n}\n","import { Point } from \"@noya-app/noya-geometry\";\nimport { SelectionRange } from \"../utils/textSelection\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  ElementProperties,\n  HandleKeyboardEventProperties,\n  ScreenPointProperties,\n  TextEditableProperties,\n} from \"./contextProperties\";\nimport { modeSwitch, NoneMode } from \"./PluginSystem\";\nimport { PointerData } from \"./pointerPlugin\";\n\ntype EditingTextMode = {\n  editingElementId: string;\n  range: SelectionRange | null;\n  type: \"editingText\";\n};\n\ntype DomTextMode = NoneMode | EditingTextMode;\n\ntype DomTextData = {\n  zoom: number;\n} & PointerData;\n\ninterface DomTextContextProperties<CanvasElement>\n  extends BaseContextProperties<DomTextMode, DomTextData>,\n    HandleKeyboardEventProperties,\n    ScreenPointProperties,\n    ElementProperties<CanvasElement>,\n    TextEditableProperties<CanvasElement> {\n  mouseDown: ({\n    clientPoint,\n    elementId,\n  }: {\n    clientPoint: Point;\n    elementId: string;\n  }) => void;\n  mouseMove: ({\n    clientPoint,\n    elementId,\n  }: {\n    clientPoint: Point;\n    elementId: string;\n  }) => void;\n  mouseUp: ({\n    clientPoint,\n    elementId,\n  }: {\n    clientPoint: Point;\n    elementId: string;\n  }) => void;\n  onBlur: (elementId: string) => void;\n}\n\nexport type DomTextPluginOptions = {};\n\nexport function domTextPlugin<CanvasElement>(\n  _options: DomTextPluginOptions = {}\n) {\n  return createCanvasPlugin({\n    name: \"editText\",\n    data: {\n      zoom: 1,\n      clickCount: 0,\n      lastClickTime: 0,\n    },\n    handlers: (context: DomTextContextProperties<CanvasElement>) => ({\n      onPointerDown(event) {\n        modeSwitch(context.getMode(), {\n          none: () => {\n            const data = context.getData();\n\n            if ((data.clickCount ?? 1) < 2) return;\n\n            const point = context.getCanvasPoint(event.nativeEvent);\n            const elements = context.filterElements({\n              at: point,\n              predicate: context.isTextEditable,\n            });\n\n            if (elements.length === 0) return;\n\n            const elementId = context.getElementId(elements[0]);\n\n            context.setMode({\n              type: \"editingText\",\n              editingElementId: elementId,\n              range: null,\n            });\n            context.setShouldHandleKeyboardEvents(false);\n            event.preventDefault();\n\n            context.mouseDown({\n              clientPoint: {\n                x: event.clientX,\n                y: event.clientY,\n              },\n              elementId,\n            });\n          },\n          editingText: (state) => {\n            const point = context.getCanvasPoint(event.nativeEvent);\n            const elements = context.filterElements({\n              at: point,\n              predicate: context.isTextEditable,\n            });\n\n            if (elements.length === 0) {\n              context.setMode({\n                type: \"none\",\n              });\n              context.onBlur(state.editingElementId);\n              context.setShouldHandleKeyboardEvents(true);\n              return;\n            }\n\n            const elementId = context.getElementId(elements[0]);\n            if (elementId !== state.editingElementId) {\n              context.setMode({\n                type: \"none\",\n              });\n              context.onBlur(state.editingElementId);\n              context.setShouldHandleKeyboardEvents(true);\n              return;\n            }\n\n            event.preventDefault();\n            context.mouseDown({\n              clientPoint: {\n                x: event.clientX,\n                y: event.clientY,\n              },\n              elementId: state.editingElementId,\n            });\n          },\n        });\n      },\n      onPointerMove(event) {\n        modeSwitch(context.getMode(), {\n          editingText: (state) => {\n            const point = {\n              x: event.clientX,\n              y: event.clientY,\n            };\n            event.preventDefault();\n            context.mouseMove({\n              clientPoint: point,\n              elementId: state.editingElementId,\n            });\n          },\n        });\n      },\n      onPointerUp(event) {\n        modeSwitch(context.getMode(), {\n          editingText: (state) => {\n            const point = {\n              x: event.clientX,\n              y: event.clientY,\n            };\n            event.preventDefault();\n            context.mouseUp({\n              clientPoint: point,\n              elementId: state.editingElementId,\n            });\n            return;\n          },\n        });\n      },\n    }),\n  });\n}\n","import {\n  BaseContextProperties,\n  createCanvasPlugin,\n  ElementProperties,\n  NoneMode,\n  PointerData,\n  ScreenPointProperties,\n} from \"@noya-app/noya-infinite-canvas\";\n\nexport function doubleClickPlugin<CanvasElement>() {\n  return createCanvasPlugin({\n    name: \"doubleClick\",\n    data: {},\n    handlers: (\n      context: BaseContextProperties<NoneMode, PointerData> &\n        ScreenPointProperties &\n        ElementProperties<CanvasElement> & {\n          handleDoubleClick: (options: { elementId: string }) => void;\n        }\n    ) => ({\n      onPointerDown(event) {\n        const data = context.getData();\n\n        if (data.pointerDown && data.clickCount === 2) {\n          const point = context.getCanvasPoint(event.nativeEvent);\n          const elements = context.filterElements({ at: point });\n\n          if (elements.length > 0) {\n            const elementId = context.getElementId(elements[0]);\n            context.handleDoubleClick({ elementId });\n          }\n        }\n      },\n    }),\n  });\n}\n","import { Point, Region } from \"@noya-app/noya-geometry\";\nimport { uuid } from \"@noya-app/noya-utils\";\nimport { DEFAULT_MOVEMENT_THRESHOLD, isMoving } from \"../utils/isMoving\";\nimport { IdentifiablePoint } from \"../utils/pointUtils\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  ElementProperties,\n  SelectableProperties,\n} from \"./contextProperties\";\nimport { BaseMode, NoneMode, modeSwitch } from \"./PluginSystem\";\nimport { PointerData } from \"./pointerPlugin\";\n\ntype DrawingMode = NoneMode | { type: \"drawing\"; region: Region };\n\ntype DrawingData = {\n  zoom: number;\n  drawnPoints: IdentifiablePoint[];\n} & Pick<PointerData, \"pointerDown\">;\n\ninterface DrawingHandlerContext<CanvasElement>\n  extends BaseContextProperties<DrawingMode, DrawingData>,\n    ElementProperties<CanvasElement>,\n    SelectableProperties<CanvasElement> {\n  canDraw?: (event: React.PointerEvent) => boolean;\n  adjustDrawingPoint?: (event: React.PointerEvent, point: Point) => Point;\n  adjustDrawingRegion?: (event: React.PointerEvent, region: Region) => Region;\n  addDrawnPoint?: (event: React.PointerEvent, point: IdentifiablePoint) => void;\n  addDrawnElement?: (\n    event: React.PointerEvent,\n    region: Region\n  ) => BaseMode | undefined;\n}\n\ntype DrawingPluginOptions = {\n  movementThreshold?: number;\n};\n\nexport function drawingPlugin<CanvasElement>(\n  options: DrawingPluginOptions = {}\n) {\n  const { movementThreshold = DEFAULT_MOVEMENT_THRESHOLD } = options;\n\n  return createCanvasPlugin({\n    name: \"drawing\",\n    data: {\n      zoom: 1,\n      drawnPoints: [],\n    },\n    handlers: ({\n      getMode,\n      setMode,\n      getData,\n      setData,\n      canDraw = () => getMode().type === \"none\",\n      adjustDrawingPoint = (_, point) => point,\n      adjustDrawingRegion = (_, region) => region,\n      addDrawnPoint = () => {},\n      addDrawnElement = () => undefined,\n    }: DrawingHandlerContext<CanvasElement>) => ({\n      onPointerDown(event) {\n        modeSwitch(getMode(), {\n          none: () => {\n            const data = getData();\n\n            if (!data.pointerDown) return;\n\n            if (!canDraw(event)) return;\n\n            // If there's a movement threshold, do nothing, wait until the pointer moves first.\n            if (movementThreshold) return;\n\n            const region = adjustDrawingRegion(event, data.pointerDown);\n            const start = {\n              ...adjustDrawingPoint(event, data.pointerDown.head),\n              id: uuid(),\n            };\n\n            setMode({ type: \"drawing\", region });\n            setData({ ...data, drawnPoints: [start] });\n\n            addDrawnPoint(event, start);\n\n            event.preventDefault();\n          },\n        });\n      },\n      onPointerMove(event) {\n        modeSwitch(getMode(), {\n          none: () => {\n            const data = getData();\n\n            if (!data.pointerDown) return;\n\n            if (!canDraw(event)) return;\n\n            if (\n              isMoving(\n                data.pointerDown.anchor,\n                data.pointerDown.head,\n                data.zoom,\n                movementThreshold\n              )\n            ) {\n              const region = adjustDrawingRegion(event, data.pointerDown);\n              const start = {\n                ...adjustDrawingPoint(event, data.pointerDown.anchor),\n                id: uuid(),\n              };\n              const end = {\n                ...adjustDrawingPoint(event, data.pointerDown.head),\n                id: uuid(),\n              };\n\n              setMode({ type: \"drawing\", region });\n              setData({ ...data, drawnPoints: [start, end] });\n\n              addDrawnPoint(event, start);\n              addDrawnPoint(event, end);\n\n              event.preventDefault();\n            }\n          },\n          drawing: () => {\n            const data = getData();\n\n            if (!data.pointerDown) return;\n\n            const region = adjustDrawingRegion(event, data.pointerDown);\n            const end = {\n              ...adjustDrawingPoint(event, data.pointerDown.head),\n              id: uuid(),\n            };\n\n            setMode({ type: \"drawing\", region });\n            setData({ ...data, drawnPoints: [...data.drawnPoints, end] });\n\n            addDrawnPoint(event, end);\n\n            event.preventDefault();\n          },\n        });\n      },\n      onPointerUp(event) {\n        const mode = getMode();\n\n        if (mode.type !== \"drawing\") return;\n\n        const data = getData();\n\n        if (!data.pointerDown) return;\n        let newMode: DrawingMode | undefined;\n\n        // If not a nearly-zero area, add the drawn element\n        if (\n          isMoving(\n            data.pointerDown.anchor,\n            data.pointerDown.head,\n            data.zoom,\n            movementThreshold\n          )\n        ) {\n          const region = adjustDrawingRegion(event, data.pointerDown);\n          const end = {\n            ...adjustDrawingPoint(event, data.pointerDown.head),\n            id: uuid(),\n          };\n\n          addDrawnPoint(event, end);\n          // this can be any mode, including ones that the drawing plugin doesn't handle\n          newMode = addDrawnElement(event, region) as DrawingMode | undefined;\n        }\n\n        setMode(newMode ?? { type: \"none\" });\n\n        // Use current data in case adding the drawn element modifies it\n        setData((data) => ({ ...data, drawnPoints: [] }));\n\n        event.preventDefault();\n      },\n    }),\n  });\n}\n","import { Point, Rect } from \"@noya-app/noya-geometry\";\nimport {\n  getSelectionRangeForUnit,\n  transformBeforeInput,\n  transformKeyDown,\n  VMeasuredCharacter,\n  VRange,\n} from \"@noya-app/text-editing\";\nimport React from \"react\";\nimport {\n  offsetRangeToSelection,\n  selectionToOffsetRange,\n} from \"../utils/textSelection\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  ElementProperties,\n  HandleKeyboardEventProperties,\n  ScreenPointProperties,\n  TextEditableProperties,\n} from \"./contextProperties\";\nimport { modeSwitch, NoneMode } from \"./PluginSystem\";\nimport { PointerData } from \"./pointerPlugin\";\nexport type { SelectionPoint, SelectionRange } from \"../utils/textSelection\";\n\nexport type EditingTextMode = {\n  editingElementId: string;\n  range: VRange | null;\n  type: \"editingText\";\n};\n\nexport type EditTextMode = NoneMode | EditingTextMode;\n\nexport type EditTextData = {\n  zoom: number;\n  selectedElementIds?: string[];\n  textDragAnchor?: number | null;\n  isDraggingText?: boolean;\n  textSelectionUnit?: \"character\" | \"word\" | \"paragraph\";\n  textInitialSelection?: { anchor: number; focus: number } | null;\n} & PointerData;\n\nexport type TextEditElement = {\n  id: string;\n  rect: Rect;\n  text: string;\n};\n\nexport type TextMeasurement = {\n  measuredCharacters: VMeasuredCharacter[];\n};\n\ninterface EditTextContextProperties<CanvasElement>\n  extends BaseContextProperties<EditTextMode, EditTextData>,\n    HandleKeyboardEventProperties,\n    ScreenPointProperties,\n    ElementProperties<CanvasElement>,\n    TextEditableProperties<CanvasElement> {\n  getTextElement: (elementId: string) => TextEditElement | undefined;\n  updateText: (elementId: string, nextText: string) => void;\n  measureText?: (element: TextEditElement) => TextMeasurement | undefined;\n  hitTestText?: (\n    element: TextEditElement,\n    parameters: { canvasPoint: Point; localPoint: Point }\n  ) => number | undefined;\n  getSelectedTextElementId?: () => string | undefined;\n  onTextPointerDown?: (event: React.PointerEvent, elementId: string) => void;\n  onTextPointerMove?: (event: React.PointerEvent, elementId: string) => void;\n  onTextPointerUp?: (event: React.PointerEvent, elementId: string) => void;\n  onBlur?: (elementId: string) => void;\n}\n\nexport type EditTextPluginOptions = {\n  triggerEvent?: \"click\" | \"doubleClick\";\n};\n\nexport function editTextPlugin<CanvasElement>(\n  options: EditTextPluginOptions = {}\n) {\n  const { triggerEvent = \"doubleClick\" } = options;\n\n  return createCanvasPlugin({\n    name: \"editText\",\n    data: {\n      zoom: 1,\n      clickCount: 0,\n      lastClickTime: 0,\n      textDragAnchor: null,\n      isDraggingText: false,\n    },\n    handlers: (context: EditTextContextProperties<CanvasElement>) => {\n      const getTextElement = (elementId: string) =>\n        context.getTextElement(elementId);\n\n      const isTriggerClick = (clickCount: number | undefined) =>\n        triggerEvent === \"doubleClick\"\n          ? (clickCount ?? 0) >= 2\n          : (clickCount ?? 0) >= 1;\n\n      const getMovementUnit = (clickCount: number | undefined) => {\n        if (!clickCount || clickCount <= 1) return \"character\";\n        return clickCount % 2 === 0 ? \"word\" : \"paragraph\";\n      };\n\n      const setSelectionRange = (nextRange: {\n        anchor: number;\n        focus: number;\n        xPosition?: number;\n      }) => {\n        context.setMode((state) => {\n          if (state.type !== \"editingText\") return state;\n\n          return {\n            ...state,\n            range: offsetRangeToSelection(nextRange),\n          };\n        });\n      };\n\n      const updateTextAndSelection = (params: {\n        elementId: string;\n        nextText: string;\n        nextRange: { anchor: number; focus: number; xPosition?: number };\n      }) => {\n        context.updateText(params.elementId, params.nextText);\n        setSelectionRange(params.nextRange);\n      };\n\n      const getSelectedTextElementId = () => {\n        const selectedFromContext = context.getSelectedTextElementId?.();\n        if (selectedFromContext) return selectedFromContext;\n\n        const data = context.getData();\n        const selectedIds = data.selectedElementIds ?? [];\n\n        if (selectedIds.length === 1) return selectedIds[0];\n\n        return undefined;\n      };\n\n      const getEditingState = () => {\n        const mode = context.getMode();\n        if (mode.type !== \"editingText\") return undefined;\n\n        const element = getTextElement(mode.editingElementId);\n\n        if (!element) return undefined;\n\n        const range = selectionToOffsetRange(\n          mode.range ?? null,\n          element.text.length\n        ) ?? {\n          anchor: element.text.length,\n          focus: element.text.length,\n          xPosition: mode.range?.xPosition,\n        };\n\n        return { element, range };\n      };\n\n      const getEditingStateOrSelectedText = () => {\n        const existing = getEditingState();\n        if (existing) return existing;\n\n        const selectedId = getSelectedTextElementId();\n        if (!selectedId) return undefined;\n\n        const element = getTextElement(selectedId);\n        if (!element) return undefined;\n\n        const range = {\n          anchor: element.text.length,\n          focus: element.text.length,\n          xPosition: undefined,\n        };\n\n        const selection = offsetRangeToSelection(range);\n\n        context.setMode({\n          type: \"editingText\",\n          editingElementId: element.id,\n          range: selection,\n        });\n        context.setShouldHandleKeyboardEvents(false);\n\n        return { element, range };\n      };\n\n      const measureText = (element: TextEditElement) =>\n        context.measureText?.(element);\n\n      const getOffsetFromEvent = (\n        elementId: string,\n        event: React.PointerEvent\n      ) => {\n        const element = getTextElement(elementId);\n        if (!element) return undefined;\n\n        const canvasPoint = context.getCanvasPoint(event.nativeEvent);\n        const localPoint = {\n          x: canvasPoint.x - element.rect.x,\n          y: canvasPoint.y - element.rect.y,\n        };\n\n        const offset =\n          context.hitTestText?.(element, { canvasPoint, localPoint }) ??\n          element.text.length;\n\n        return { offset, element };\n      };\n\n      const handleTextMouseDown = (\n        elementId: string,\n        event: React.PointerEvent\n      ) => {\n        const result = getOffsetFromEvent(elementId, event);\n        if (!result) return;\n\n        const data = context.getData();\n        const movementUnit = getMovementUnit(data.clickCount);\n        const measuredCharacters =\n          measureText(result.element)?.measuredCharacters ?? [];\n\n        const offsetRange = getSelectionRangeForUnit({\n          measuredCharacters,\n          offset: result.offset,\n          unit: movementUnit,\n          textLength: result.element.text.length,\n        });\n\n        context.setData((current) => ({\n          ...current,\n          textDragAnchor: result.offset,\n          isDraggingText: true,\n          textSelectionUnit: movementUnit,\n          textInitialSelection: offsetRange,\n        }));\n\n        setSelectionRange(offsetRange);\n      };\n\n      const handleTextMouseMove = (\n        elementId: string,\n        event: React.PointerEvent\n      ) => {\n        const data = context.getData();\n        const dragAnchor = data.textDragAnchor ?? null;\n        if (!data.isDraggingText || dragAnchor === null) return;\n\n        const result = getOffsetFromEvent(elementId, event);\n        if (!result) return;\n\n        const movementUnit = data.textSelectionUnit ?? \"character\";\n        const measuredCharacters =\n          measureText(result.element)?.measuredCharacters ?? [];\n\n        const currentRange = getSelectionRangeForUnit({\n          measuredCharacters,\n          offset: result.offset,\n          unit: movementUnit,\n          textLength: result.element.text.length,\n        });\n\n        let offsetRange: { anchor: number; focus: number };\n\n        if (movementUnit === \"character\") {\n          offsetRange = {\n            anchor: dragAnchor,\n            focus: result.offset,\n          };\n        } else {\n          const initial = data.textInitialSelection ?? {\n            anchor: dragAnchor,\n            focus: dragAnchor,\n          };\n\n          const min = Math.min(\n            initial.anchor,\n            initial.focus,\n            currentRange.anchor,\n            currentRange.focus\n          );\n          const max = Math.max(\n            initial.anchor,\n            initial.focus,\n            currentRange.anchor,\n            currentRange.focus\n          );\n\n          offsetRange = { anchor: min, focus: max };\n        }\n\n        setSelectionRange(offsetRange);\n      };\n\n      const handleTextMouseUp = () => {\n        context.setData((current) => ({\n          ...current,\n          isDraggingText: false,\n          textDragAnchor: null,\n          textSelectionUnit: undefined,\n          textInitialSelection: null,\n        }));\n      };\n\n      const handleTextBlur = () => {\n        context.setData((current) => ({\n          ...current,\n          isDraggingText: false,\n          textDragAnchor: null,\n          textSelectionUnit: undefined,\n          textInitialSelection: null,\n        }));\n      };\n\n      return {\n        onPointerDown(event) {\n          modeSwitch(context.getMode(), {\n            none: () => {\n              const data = context.getData();\n\n              if (!isTriggerClick(data.clickCount)) return;\n\n              const point = context.getCanvasPoint(event.nativeEvent);\n              const elements = context.filterElements({\n                at: point,\n                predicate: context.isTextEditable,\n              });\n\n              if (elements.length === 0) return;\n\n              const elementId = context.getElementId(elements[0]);\n\n              context.setMode({\n                type: \"editingText\",\n                editingElementId: elementId,\n                range: null,\n              });\n              context.setShouldHandleKeyboardEvents(false);\n              event.preventDefault();\n\n              handleTextMouseDown(elementId, event);\n              context.onTextPointerDown?.(event, elementId);\n            },\n            editingText: (state) => {\n              const data = context.getData();\n              const point = context.getCanvasPoint(event.nativeEvent);\n              const elements = context.filterElements({\n                at: point,\n                predicate: context.isTextEditable,\n              });\n\n              if (elements.length === 0) {\n                context.setMode({\n                  type: \"none\",\n                });\n                context.onBlur?.(state.editingElementId);\n                handleTextBlur();\n                context.setShouldHandleKeyboardEvents(true);\n                return;\n              }\n\n              const elementId = context.getElementId(elements[0]);\n              if (elementId !== state.editingElementId) {\n                if (\n                  triggerEvent === \"click\" &&\n                  isTriggerClick(data.clickCount)\n                ) {\n                  context.onBlur?.(state.editingElementId);\n                  handleTextBlur();\n\n                  context.setMode({\n                    type: \"editingText\",\n                    editingElementId: elementId,\n                    range: null,\n                  });\n                  context.setShouldHandleKeyboardEvents(false);\n                  event.preventDefault();\n\n                  handleTextMouseDown(elementId, event);\n                  context.onTextPointerDown?.(event, elementId);\n                  return;\n                }\n\n                context.setMode({\n                  type: \"none\",\n                });\n                context.onBlur?.(state.editingElementId);\n                handleTextBlur();\n                context.setShouldHandleKeyboardEvents(true);\n                return;\n              }\n\n              event.preventDefault();\n              handleTextMouseDown(state.editingElementId, event);\n              context.onTextPointerDown?.(event, state.editingElementId);\n            },\n          });\n        },\n        onPointerMove(event) {\n          modeSwitch(context.getMode(), {\n            editingText: (state) => {\n              event.preventDefault();\n              handleTextMouseMove(state.editingElementId, event);\n              context.onTextPointerMove?.(event, state.editingElementId);\n            },\n          });\n        },\n        onPointerUp(event) {\n          modeSwitch(context.getMode(), {\n            editingText: (state) => {\n              event.preventDefault();\n              handleTextMouseUp();\n              context.onTextPointerUp?.(event, state.editingElementId);\n              return;\n            },\n          });\n        },\n        onBeforeInput(event) {\n          modeSwitch(context.getMode(), {\n            editingText: () => {\n              const editingState = getEditingStateOrSelectedText();\n              if (!editingState) return;\n\n              const { element, range } = editingState;\n              const measuredCharacters =\n                measureText(element)?.measuredCharacters ?? [];\n              event.preventDefault();\n\n              const result = transformBeforeInput({\n                event,\n                text: element.text,\n                range,\n                measuredCharacters,\n              });\n\n              if (!result) return;\n\n              updateTextAndSelection({\n                elementId: element.id,\n                nextText: result.nextText,\n                nextRange: result.nextRange,\n              });\n            },\n          });\n        },\n        onKeyDown(event) {\n          modeSwitch(context.getMode(), {\n            editingText: () => {\n              const editingState = getEditingStateOrSelectedText();\n              if (!editingState) return;\n\n              const { element, range } = editingState;\n              const measuredCharacters =\n                measureText(element)?.measuredCharacters ?? [];\n\n              const nextRange = transformKeyDown({\n                event,\n                measuredCharacters,\n                range,\n              });\n\n              if (nextRange) {\n                setSelectionRange(nextRange);\n                event.preventDefault();\n              }\n            },\n          });\n        },\n      };\n    },\n  });\n}\n","import { clamp } from \"@noya-app/noya-utils\";\nimport { VOffsetRange, VRange } from \"@noya-app/text-editing\";\n\nexport type SelectionPoint = VRange[\"anchor\"];\nexport type SelectionRange = VRange;\n\nexport const TEXT_SELECTION_PATH = [0];\n\nexport function selectionToOffsetRange(\n  range: SelectionRange | null,\n  textLength: number\n): VOffsetRange | null {\n  if (!range) return null;\n\n  return {\n    anchor: clamp(range.anchor.column, 0, textLength),\n    focus: clamp(range.focus.column, 0, textLength),\n    xPosition: range.xPosition,\n  };\n}\n\nexport function offsetRangeToSelection(range: VOffsetRange): SelectionRange {\n  return {\n    anchor: { path: TEXT_SELECTION_PATH, column: range.anchor },\n    focus: { path: TEXT_SELECTION_PATH, column: range.focus },\n    xPosition: range.xPosition,\n  };\n}\n","import { Point } from \"@noya-app/noya-geometry\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport { BaseContextProperties, ElementProperties } from \"./contextProperties\";\nimport { modeSwitch, NoneMode } from \"./PluginSystem\";\nimport { PointerData } from \"./pointerPlugin\";\n\nexport type EraserMode = NoneMode | { type: \"erasing\" };\n\nexport type EraserData = {\n  markedForErasureElementIds: string[];\n} & PointerData;\n\nexport interface EraserContextProperties<CanvasElement>\n  extends BaseContextProperties<EraserMode, EraserData>,\n    ElementProperties<CanvasElement> {\n  canErase?: (event: React.PointerEvent) => boolean;\n  adjustErasePoint?: (event: React.PointerEvent, point: Point) => Point;\n  onEraseElements?: (elementIds: string[]) => void;\n}\n\nexport function eraserPlugin<CanvasElement>() {\n  return createCanvasPlugin({\n    name: \"eraser\",\n    data: {\n      markedForErasureElementIds: [],\n    },\n    handlers: ({\n      getMode,\n      setMode,\n      getData,\n      setData,\n      canErase = () => true,\n      adjustErasePoint = (_, point) => point,\n      getElementId,\n      ...context\n    }: EraserContextProperties<CanvasElement>) => ({\n      onPointerDown(event: React.PointerEvent<Element>) {\n        modeSwitch(getMode(), {\n          none: () => {\n            const data = getData();\n\n            if (!data.pointerDown || !canErase(event)) return;\n\n            setMode({ type: \"erasing\" });\n\n            const elements = context.filterElements({\n              at: data.pointerDown.head,\n              predicate: () => true,\n            });\n\n            if (elements.length > 0) {\n              setData({\n                ...data,\n                markedForErasureElementIds: elements.map(getElementId),\n              });\n            }\n\n            event.preventDefault();\n          },\n        });\n      },\n      onPointerMove(event: React.PointerEvent<Element>) {\n        modeSwitch(getMode(), {\n          erasing: () => {\n            const data = getData();\n\n            if (!data.pointerDown) return;\n\n            const point = adjustErasePoint(event, data.pointerDown.head);\n\n            const elements = context.filterElements({\n              at: point,\n              predicate: () => true,\n            });\n\n            if (elements.length > 0) {\n              setData({\n                ...data,\n                markedForErasureElementIds: mergeUnique(\n                  data.markedForErasureElementIds,\n                  elements.map(getElementId)\n                ),\n              });\n            }\n\n            event.preventDefault();\n          },\n        });\n      },\n      onPointerUp(event: React.PointerEvent<Element>) {\n        modeSwitch(getMode(), {\n          erasing: () => {\n            const data = getData();\n\n            if (!data.pointerDown) return;\n\n            const elements = context.filterElements({\n              at: data.pointerDown.head,\n              predicate: () => true,\n            });\n\n            const markedForErasureElementIds =\n              elements.length > 0\n                ? mergeUnique(\n                    data.markedForErasureElementIds,\n                    elements.map(getElementId)\n                  )\n                : data.markedForErasureElementIds;\n\n            context.onEraseElements?.(markedForErasureElementIds);\n\n            setMode({ type: \"none\" });\n            setData({ ...data, markedForErasureElementIds: [] });\n\n            event.preventDefault();\n          },\n        });\n      },\n    }),\n  });\n}\n\nfunction mergeUnique<T>(a: T[], b: T[]) {\n  return Array.from(new Set([...a, ...b]));\n}\n","import { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  CanvasRefProperties,\n} from \"./contextProperties\";\nimport { NoneMode } from \"./PluginSystem\";\n\nexport type FocusMode = NoneMode;\n\nexport type FocusData = {};\n\nexport interface FocusContextContext\n  extends BaseContextProperties<FocusMode, FocusData>,\n    CanvasRefProperties {}\n\nexport function focusPlugin() {\n  return createCanvasPlugin({\n    name: \"focus\",\n    data: {},\n    handlers: (context: FocusContextContext) => ({\n      onPointerDown() {\n        context.canvasRef.current?.focus();\n      },\n    }),\n  });\n}\n","import { AffineTransform, Point, Rect } from \"@noya-app/noya-geometry\";\nimport { clamp01 } from \"@noya-app/noya-utils\";\nimport {\n  GradientEditorGradient,\n  GradientStopHandle,\n} from \"./gradientEditorPlugin\";\n\nexport type GradientEditorLinearGradient = {\n  from: Point;\n  to: Point;\n  stops: {\n    color: string;\n    offset: number;\n  }[];\n};\n\nexport type GradientEditorDetails = {\n  gradient: GradientEditorGradient;\n  stopMap: Map<string, number>;\n};\n\nexport function createGradientEditorDetails({\n  linearGradient,\n  artRect,\n  transform,\n}: {\n  linearGradient: GradientEditorLinearGradient;\n  artRect: Rect;\n  transform: AffineTransform;\n}): GradientEditorDetails {\n  const rect = transform.applyTo(artRect);\n\n  const from = {\n    x: clamp01(linearGradient.from.x),\n    y: clamp01(linearGradient.from.y),\n  };\n\n  const to = {\n    x: clamp01(linearGradient.to.x),\n    y: clamp01(linearGradient.to.y),\n  };\n\n  const stops: GradientStopHandle[] = linearGradient.stops.map(\n    (stop, index, allStops) => {\n      const position =\n        allStops.length > 1\n          ? clamp01(stop.offset ?? index / (allStops.length - 1))\n          : 0;\n\n      const normalizedPoint = {\n        x: from.x + (to.x - from.x) * position,\n        y: from.y + (to.y - from.y) * position,\n      };\n\n      const point = transform.applyTo({\n        x: artRect.x + normalizedPoint.x * artRect.width,\n        y: artRect.y + normalizedPoint.y * artRect.height,\n      });\n\n      const type: GradientStopHandle[\"type\"] =\n        index === 0 ? \"start\" : index === allStops.length - 1 ? \"end\" : \"stop\";\n\n      return {\n        id: `stop-${index}`,\n        index,\n        type,\n        position,\n        point,\n        color: stop.color,\n      };\n    }\n  );\n\n  const stopMap = new Map(stops.map((stop) => [stop.id, stop.index]));\n\n  return {\n    gradient: {\n      rect,\n      stops,\n    },\n    stopMap,\n  };\n}\n","import { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  ElementProperties,\n  HighlightableProperties,\n  ScreenPointProperties,\n} from \"./contextProperties\";\nimport { NoneMode } from \"./PluginSystem\";\n\nexport type HighlightMode = NoneMode;\n\nexport type HighlightData = {\n  highlightedElementId: string | undefined;\n};\n\nexport interface HighlightContextProperties<CanvasElement>\n  extends BaseContextProperties<HighlightMode, HighlightData>,\n    ScreenPointProperties,\n    ElementProperties<CanvasElement>,\n    HighlightableProperties<CanvasElement> {}\n\nexport function highlightPlugin<CanvasElement>() {\n  return createCanvasPlugin({\n    name: \"highlight\",\n    data: {\n      highlightedElementId: undefined,\n    },\n    handlers: (context: HighlightContextProperties<CanvasElement>) => ({\n      onPointerMove(event) {\n        const mode = context.getMode();\n\n        if (mode.type !== \"none\") return;\n\n        const point = context.getCanvasPoint(event.nativeEvent);\n        const elements = context.filterElements({\n          at: point,\n          predicate: context.isHighlightable,\n        });\n        const firstElementId =\n          elements.length > 0 ? context.getElementId(elements[0]) : undefined;\n\n        const data = context.getData();\n\n        if (firstElementId !== data.highlightedElementId) {\n          context.setData({ ...data, highlightedElementId: firstElementId });\n        }\n      },\n      onPointerLeave() {\n        const mode = context.getMode();\n\n        if (mode.type !== \"none\") return;\n\n        const data = context.getData();\n\n        if (data.highlightedElementId) {\n          context.setData({ ...data, highlightedElementId: undefined });\n        }\n      },\n    }),\n  });\n}\n","import { Rect, rectContainsPoint, Region } from \"@noya-app/noya-geometry\";\nimport { getPointHandles } from \"../utils/dragHandleUtils\";\nimport { isMoving } from \"../utils/isMoving\";\nimport {\n  DEFAULT_POINT_HANDLE_SIZE,\n  getAbsolutizeTransform,\n  IdentifiablePoint,\n} from \"../utils/pointUtils\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  ScreenPointProperties,\n} from \"./contextProperties\";\nimport { NoneMode } from \"./PluginSystem\";\nimport { PointerData } from \"./pointerPlugin\";\n\nexport type LineHandleCoordinates = {\n  rect: Rect;\n  start: IdentifiablePoint;\n  end: IdentifiablePoint;\n};\n\ntype LineMode<StateSnapshot> =\n  | NoneMode\n  | {\n      type: \"movingLinePoint\";\n      region: Region;\n      snapshot: StateSnapshot;\n      id: string;\n    };\n\nexport type LineData = {\n  highlightedPointId?: string;\n  pointHandleSize: number;\n  zoom: number;\n} & Pick<PointerData, \"pointerDown\" | \"pointer\">;\n\nexport type LinePluginOptions = {\n  pointHandleSize?: number;\n  movementThreshold?: number;\n};\n\nexport interface LineContextProperties<StateSnapshot>\n  extends BaseContextProperties<LineMode<StateSnapshot>, LineData>,\n    ScreenPointProperties {\n  getLine: () => LineHandleCoordinates | undefined;\n  getStateSnapshot: () => StateSnapshot;\n  moveLinePoint: (params: {\n    id: string;\n    region: Region;\n    snapshot: StateSnapshot;\n  }) => void;\n  canEditLine?: () => boolean;\n}\n\nfunction getLineHandles(\n  line: LineHandleCoordinates,\n  data: Pick<LineData, \"pointHandleSize\" | \"zoom\">\n) {\n  const transform = getAbsolutizeTransform(line.rect);\n\n  return getPointHandles({\n    points: [line.start, line.end].map((point) => ({\n      ...transform.applyTo(point),\n      id: point.id,\n    })),\n    data,\n  });\n}\n\nexport function linePlugin<StateSnapshot>(options: LinePluginOptions = {}) {\n  const { pointHandleSize = DEFAULT_POINT_HANDLE_SIZE, movementThreshold = 0 } =\n    options;\n\n  return createCanvasPlugin({\n    name: \"line\",\n    data: {\n      highlightedPointId: undefined,\n      pointHandleSize,\n      zoom: 1,\n    },\n    handlers: (context: LineContextProperties<StateSnapshot>) => ({\n      onPointerDown(event) {\n        if (context.getMode().type !== \"none\") return;\n        if (context.canEditLine && !context.canEditLine()) return;\n\n        const data = context.getData();\n        const pointerDown = data.pointerDown;\n\n        if (!pointerDown) return;\n\n        const line = context.getLine();\n        if (!line) return;\n\n        const handles = getLineHandles(line, data);\n        const handle = handles.find((candidate) =>\n          rectContainsPoint(candidate.rect, pointerDown.anchor)\n        );\n\n        if (!handle) return;\n\n        context.setMode({\n          type: \"movingLinePoint\",\n          region: pointerDown,\n          snapshot: context.getStateSnapshot(),\n          id: handle.id,\n        });\n\n        event.preventDefault();\n      },\n      onPointerMove(event) {\n        const canEditLine = context.canEditLine?.() ?? true;\n\n        if (!canEditLine) return;\n\n        const data = context.getData();\n        const line = context.getLine();\n\n        if (!line) {\n          if (data.highlightedPointId) {\n            context.setData((current) => ({\n              ...current,\n              highlightedPointId: undefined,\n            }));\n          }\n\n          return;\n        }\n\n        const handles = getLineHandles(line, data);\n        const mode = context.getMode();\n\n        if (mode.type === \"none\") {\n          if (!data.pointerDown) {\n            const pointer = context.getCanvasPoint(event.nativeEvent);\n            const hoveredHandle = handles.find((handle) =>\n              rectContainsPoint(handle.rect, pointer)\n            );\n\n            if (hoveredHandle?.id !== data.highlightedPointId) {\n              context.setData((current) => ({\n                ...current,\n                highlightedPointId: hoveredHandle?.id,\n              }));\n            }\n\n            return;\n          }\n\n          return;\n        }\n\n        if (mode.type === \"movingLinePoint\" && data.pointerDown) {\n          if (\n            isMoving(\n              data.pointerDown.anchor,\n              data.pointerDown.head,\n              data.zoom,\n              movementThreshold\n            )\n          ) {\n            context.moveLinePoint({\n              id: mode.id,\n              region: data.pointerDown,\n              snapshot: mode.snapshot,\n            });\n\n            event.preventDefault();\n          }\n        }\n      },\n      // eslint-disable-next-line @shopify/prefer-early-return\n      onPointerUp(event) {\n        if (context.getMode().type === \"movingLinePoint\") {\n          context.setMode({ type: \"none\" });\n          event.preventDefault();\n        }\n      },\n      onPointerLeave() {\n        if (context.getMode().type !== \"none\") return;\n\n        const data = context.getData();\n\n        if (data.highlightedPointId) {\n          context.setData((current) => ({\n            ...current,\n            highlightedPointId: undefined,\n          }));\n        }\n      },\n      onPointerCancel() {\n        if (context.getMode().type !== \"none\") {\n          context.setMode({ type: \"none\" });\n        }\n      },\n    }),\n    getCursor: ({ data, mode }) => {\n      if (\n        (mode.type === \"movingLinePoint\" || mode.type === \"none\") &&\n        data.highlightedPointId\n      ) {\n        return \"pointer\";\n      }\n\n      return undefined;\n    },\n  });\n}\n","import { getRegionDelta, Point } from \"@noya-app/noya-geometry\";\nimport { DEFAULT_MOVEMENT_THRESHOLD, isMoving } from \"../utils/isMoving\";\nimport { getMovingOptionsForEvent, MovingOptions } from \"../utils/movingUtils\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  ElementProperties,\n  MovableProperties,\n} from \"./contextProperties\";\nimport { modeSwitch, NoneMode } from \"./PluginSystem\";\nimport { PointerData } from \"./pointerPlugin\";\n\nexport type MoveMode<StateSnapshot> =\n  | NoneMode\n  | { type: \"moving\"; delta: Point; snapshot: StateSnapshot };\n\nexport type MoveData = {\n  zoom: number;\n  selectedElementIds: string[];\n} & Pick<PointerData, \"pointerDown\">;\n\nexport type MoveElementParameters<StateSnapshot> = {\n  elementIds: string[];\n  delta: Point;\n  snapshot: StateSnapshot;\n  options: MovingOptions;\n};\n\nexport type DuplicateElementsResult<StateSnapshot> = Pick<\n  MoveElementParameters<StateSnapshot>,\n  \"elementIds\" | \"snapshot\"\n>;\n\nexport interface MoveContextProperties<CanvasElement, StateSnapshot>\n  extends BaseContextProperties<MoveMode<StateSnapshot>, MoveData>,\n    ElementProperties<CanvasElement>,\n    MovableProperties<CanvasElement> {\n  adjustMoveDelta?: (\n    event: React.PointerEvent,\n    options: MoveElementParameters<StateSnapshot>\n  ) => Point;\n  finalizeMove?: (options: MoveElementParameters<StateSnapshot>) => void;\n  duplicateElements?: (\n    event: React.PointerEvent,\n    options: MoveElementParameters<StateSnapshot>\n  ) => DuplicateElementsResult<StateSnapshot> | undefined;\n  getStateSnapshot: () => StateSnapshot;\n  moveElements: (parameters: MoveElementParameters<StateSnapshot>) => void;\n}\n\nexport type MovePluginOptions = {\n  movementThreshold?: number;\n};\n\nexport function movePlugin<CanvasElement, StateSnapshot>(\n  options: MovePluginOptions = {}\n) {\n  const { movementThreshold = DEFAULT_MOVEMENT_THRESHOLD } = options;\n\n  return createCanvasPlugin({\n    name: \"move\",\n    data: {\n      zoom: 1,\n      selectedElementIds: [],\n    },\n    handlers: ({\n      getMode,\n      setMode,\n      getData,\n      setData,\n      adjustMoveDelta = (_, options) => options.delta,\n      ...context\n    }: MoveContextProperties<CanvasElement, StateSnapshot>) => ({\n      onPointerMove(event) {\n        modeSwitch(getMode(), {\n          none: () => {\n            const data = getData();\n\n            if (!data.pointerDown) return;\n\n            const elements = context.filterElements({\n              at: data.pointerDown.anchor,\n              predicate: context.isMovable,\n            });\n\n            if (\n              elements.length > 0 &&\n              isMoving(\n                data.pointerDown.anchor,\n                data.pointerDown.head,\n                data.zoom,\n                movementThreshold\n              )\n            ) {\n              const snapshot = context.getStateSnapshot();\n\n              const baseParameters: MoveElementParameters<StateSnapshot> = {\n                elementIds: data.selectedElementIds,\n                delta: getRegionDelta(data.pointerDown),\n                snapshot,\n                options: getMovingOptionsForEvent(event),\n              };\n\n              const duplicated = event.altKey\n                ? context.duplicateElements?.(event, baseParameters)\n                : undefined;\n\n              const parameters = duplicated\n                ? { ...baseParameters, ...duplicated }\n                : baseParameters;\n\n              if (duplicated) {\n                setData((data) => ({\n                  ...data,\n                  selectedElementIds: duplicated.elementIds,\n                }));\n              }\n\n              const delta = adjustMoveDelta(event, parameters);\n\n              setMode({\n                type: \"moving\",\n                delta,\n                snapshot: parameters.snapshot,\n              });\n\n              event.preventDefault();\n            }\n          },\n          moving: ({ snapshot }) => {\n            const data = getData();\n\n            if (!data.pointerDown) return;\n\n            const parameters: MoveElementParameters<StateSnapshot> = {\n              elementIds: data.selectedElementIds,\n              delta: getRegionDelta(data.pointerDown),\n              snapshot,\n              options: getMovingOptionsForEvent(event),\n            };\n\n            const delta = adjustMoveDelta(event, parameters);\n\n            setMode({ type: \"moving\", delta, snapshot });\n\n            context.moveElements?.({ ...parameters, delta });\n\n            event.preventDefault();\n          },\n        });\n      },\n      onPointerUp(event) {\n        const mode = getMode();\n\n        if (mode.type !== \"moving\") return;\n\n        const data = getData();\n\n        const parameters: MoveElementParameters<StateSnapshot> = {\n          elementIds: data.selectedElementIds,\n          delta: mode.delta,\n          snapshot: mode.snapshot,\n          options: getMovingOptionsForEvent(event),\n        };\n\n        context.finalizeMove?.(parameters);\n\n        setMode({ type: \"none\" });\n\n        event.preventDefault();\n      },\n    }),\n  });\n}\n","import {\n  AffineTransform,\n  getRegionDelta,\n  Point,\n  Rect,\n  Region,\n  Size,\n  unionRects,\n} from \"@noya-app/noya-geometry\";\nimport {\n  getBestSnapDelta,\n  getElementSnapDelta,\n  getGridSnapDelta,\n  getValuesOnAxis,\n} from \"./snapUtils\";\n\nexport type MovingOptions = {\n  constrainToSingleAxis?: boolean;\n  ignoreSnapping?: boolean;\n};\n\nexport function getMovingOptionsForEvent({\n  shiftKey,\n  ctrlKey,\n}: {\n  shiftKey: boolean;\n  ctrlKey: boolean;\n}): MovingOptions {\n  return {\n    constrainToSingleAxis: shiftKey,\n    ignoreSnapping: ctrlKey,\n  };\n}\n\nexport function getMoveTransform(\n  delta: Point | Region,\n  { constrainToSingleAxis }: MovingOptions\n) {\n  if (\"anchor\" in delta) {\n    delta = getRegionDelta(delta);\n  }\n\n  if (constrainToSingleAxis) {\n    if (Math.abs(delta.x) > Math.abs(delta.y)) {\n      return AffineTransform.translate(delta.x, 0);\n    } else {\n      return AffineTransform.translate(0, delta.y);\n    }\n  } else {\n    return AffineTransform.translate(delta);\n  }\n}\n\nexport function getMoveSnapDelta({\n  movingRects,\n  stationaryRects,\n  delta,\n  gridSize,\n  options,\n}: {\n  movingRects: Rect[];\n  stationaryRects: Rect[];\n  delta: Point;\n  gridSize: Size;\n  options: MovingOptions;\n}) {\n  const movingBoundingBox = unionRects(...movingRects);\n\n  const transform = getMoveTransform(delta, options);\n  const transformedMovingRect = transform.applyTo(movingBoundingBox);\n\n  const possibleSnapsX = [\n    getElementSnapDelta({\n      movingValues: getValuesOnAxis(transformedMovingRect, \"x\"),\n      stationaryValues: getValuesOnAxis(stationaryRects, \"x\"),\n    }),\n    getGridSnapDelta({\n      value: transformedMovingRect.x,\n      gridSize: gridSize.width,\n    }),\n  ];\n\n  const possibleSnapsY = [\n    getElementSnapDelta({\n      movingValues: getValuesOnAxis(transformedMovingRect, \"y\"),\n      stationaryValues: getValuesOnAxis(stationaryRects, \"y\"),\n    }),\n    getGridSnapDelta({\n      value: transformedMovingRect.y,\n      gridSize: gridSize.height,\n    }),\n  ];\n\n  const snapDelta = {\n    x: getBestSnapDelta(possibleSnapsX),\n    y: getBestSnapDelta(possibleSnapsY),\n  };\n\n  return {\n    x: delta.x + snapDelta.x,\n    y: delta.y + snapDelta.y,\n  };\n}\n","import { createBounds, Rect, unionRects } from \"@noya-app/noya-geometry\";\nimport { cartesianProduct, unique } from \"@noya-app/noya-utils\";\n\nexport type SnapLine = {\n  x1: number;\n  y1: number;\n  x2: number;\n  y2: number;\n};\n\nfunction getValuesOnAxisForRect(\n  rect: Rect,\n  axis: \"x\" | \"y\"\n): [number, number, number] {\n  const bounds = createBounds(rect);\n\n  return axis === \"x\"\n    ? [bounds.minX, bounds.midX, bounds.maxX]\n    : [bounds.minY, bounds.midY, bounds.maxY];\n}\n\nexport function getValuesOnAxis(\n  rects: Rect | Rect[],\n  axis: \"x\" | \"y\"\n): number[] {\n  if (!Array.isArray(rects)) {\n    rects = [rects];\n  }\n\n  return unique(rects.flatMap((rect) => getValuesOnAxisForRect(rect, axis)));\n}\n\nexport function getElementSnapDelta({\n  movingValues,\n  stationaryValues,\n  proximity = 5,\n}: {\n  movingValues: number[];\n  stationaryValues: number[];\n  proximity?: number;\n}): number | null {\n  const pairs = cartesianProduct(movingValues, stationaryValues);\n  const sortedPairs = pairs.sort(([a1, a2], [b1, b2]) => {\n    const delta1 = Math.abs(a1 - a2);\n    const delta2 = Math.abs(b1 - b2);\n    return delta1 - delta2;\n  });\n\n  const closestPair = sortedPairs.at(0);\n\n  if (!closestPair) return null;\n\n  const delta = closestPair[0] - closestPair[1];\n\n  if (Math.abs(delta) > proximity) return null;\n\n  return -delta;\n}\n\nconst EPSILON = 0.001;\n\nfunction isNearlyEqual(a: number, b: number, epsilon = EPSILON): boolean {\n  return Math.abs(a - b) <= epsilon;\n}\n\nexport function getSnapLines({\n  movingRect,\n  stationaryRects,\n  axis,\n  proximity = 1,\n}: {\n  movingRect: Rect;\n  stationaryRects: Rect[];\n  axis: \"x\" | \"y\";\n  proximity?: number;\n}): SnapLine[] {\n  const movingValues = getValuesOnAxis(movingRect, axis);\n\n  const lines = movingValues.flatMap((value): SnapLine[] => {\n    const relevantRects = stationaryRects.filter((rect) => {\n      return getValuesOnAxis(rect, axis).some((v) =>\n        isNearlyEqual(v, value, proximity)\n      );\n    });\n\n    if (relevantRects.length === 0) return [];\n\n    const fullRect = unionRects(...relevantRects, movingRect);\n    const bounds = createBounds(fullRect);\n\n    if (axis === \"x\") {\n      return [{ x1: value, y1: bounds.minY, x2: value, y2: bounds.maxY }];\n    } else {\n      return [{ x1: bounds.minX, y1: value, x2: bounds.maxX, y2: value }];\n    }\n  });\n\n  return lines;\n}\n\nexport function getGridSnapDelta({\n  value,\n  gridSize,\n}: {\n  value: number;\n  gridSize: number;\n}): number {\n  const nearestValue = Math.round(value / gridSize) * gridSize;\n\n  const delta = nearestValue - value;\n\n  return delta;\n}\n\nexport function getBestSnapDelta(snaps: (number | null)[]): number {\n  const nonNullSnaps = snaps.filter((snap) => snap !== null);\n  return nonNullSnaps.at(0) ?? 0;\n}\n","import { Point, Size, roundPoint } from \"@noya-app/noya-geometry\";\nimport { wheelValues } from \"../utils/wheelUtils\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  HandleKeyboardEventProperties,\n  ScreenPointProperties,\n} from \"./contextProperties\";\nimport { NoneMode, modeSwitch } from \"./PluginSystem\";\n\ntype ReturnTo = \"none\" | \"panMode\";\n\nexport type PanMode =\n  | NoneMode\n  | { type: \"panMode\" }\n  | { type: \"maybePan\"; origin: Point; returnTo: ReturnTo }\n  | { type: \"panning\"; previous: Point; next: Point; returnTo: ReturnTo };\n\nexport type PanData = {\n  size: Size;\n  origin: Point;\n};\n\nexport interface PanContextProperties\n  extends BaseContextProperties<PanMode, PanData>,\n    HandleKeyboardEventProperties,\n    ScreenPointProperties {\n  isHandActive?: () => boolean;\n}\n\nexport type PanOptions = {\n  onWheelShouldPreventDefault?: boolean;\n  modiferKeyShouldDisablePan?: boolean;\n};\n\nexport function panPlugin(options: PanOptions = {}) {\n  const { modiferKeyShouldDisablePan = true } = options;\n\n  return createCanvasPlugin({\n    name: \"pan\",\n    data: {\n      size: { width: 0, height: 0 },\n      origin: { x: 0, y: 0 },\n    },\n    handlers: (context: PanContextProperties) => ({\n      onWheel: (event) => {\n        // Skip panning when modifier key is pressed (for zoom functionality)\n        if (modiferKeyShouldDisablePan && (event.metaKey || event.ctrlKey)) {\n          return;\n        }\n\n        const data = context.getData();\n        const delta = wheelValues(event.nativeEvent);\n\n        context.setData({\n          ...data,\n          origin: roundPoint({\n            x: data.origin.x - delta.x,\n            y: data.origin.y - delta.y,\n          }),\n        });\n\n        // React uses a passive listener, so we usually don't prevent the default\n        if (options.onWheelShouldPreventDefault) {\n          event.preventDefault();\n        }\n      },\n      onKeyDown: (event) =>\n        modeSwitch(context.getMode(), {\n          none: () =>\n            context.handleKeyboardEvent({\n              Space: () => {\n                context.setMode({ type: \"panMode\" });\n                context.setReadOnly(true);\n              },\n            })(event),\n        }),\n      onKeyUp: (event) => {\n        const state = context.getMode();\n\n        if (\n          state.type === \"maybePan\" ||\n          state.type === \"panning\" ||\n          state.type === \"panMode\"\n        ) {\n          context.handleKeyboardEvent({\n            Space: () => {\n              context.setMode({ type: \"none\" });\n              context.setReadOnly(false);\n            },\n          })(event);\n        }\n      },\n      onPointerDown: (event) => {\n        const mode = context.getMode();\n        const handActive = context.isHandActive?.() ?? false;\n\n        if (handActive || mode.type === \"panMode\") {\n          const point = context.getScreenPoint(event.nativeEvent);\n          context.setMode({\n            type: \"maybePan\",\n            origin: point,\n            returnTo: handActive ? \"none\" : \"panMode\",\n          });\n\n          event.preventDefault();\n        }\n      },\n      onPointerMove: (event) =>\n        modeSwitch(context.getMode(), {\n          maybePan: ({ origin, returnTo }) => {\n            const point = context.getScreenPoint(event.nativeEvent);\n            context.setMode({\n              type: \"panning\",\n              previous: origin,\n              next: point,\n              returnTo: returnTo,\n            });\n\n            event.preventDefault();\n          },\n          panning: ({ next, returnTo }) => {\n            const data = context.getData();\n            const point = context.getScreenPoint(event.nativeEvent);\n\n            context.setData({\n              ...data,\n              origin: roundPoint({\n                x: data.origin.x + point.x - next.x,\n                y: data.origin.y + point.y - next.y,\n              }),\n            });\n\n            context.setMode({\n              type: \"panning\",\n              previous: next,\n              next: point,\n              returnTo: returnTo,\n            });\n          },\n        }),\n      onPointerUp: (event) =>\n        modeSwitch(context.getMode(), {\n          maybePan: ({ returnTo }) => {\n            context.setMode({ type: returnTo });\n\n            event.preventDefault();\n          },\n          panning: ({ returnTo }) => {\n            context.setMode({ type: returnTo });\n\n            event.preventDefault();\n          },\n        }),\n    }),\n    getCursor: ({ mode }) => {\n      if (mode.type === \"panMode\") {\n        return \"grab\";\n      } else if (mode.type === \"maybePan\" || mode.type === \"panning\") {\n        return \"grabbing\";\n      }\n\n      return undefined;\n    },\n  });\n}\n","import { Point } from \"@noya-app/noya-geometry\";\n\n// MIT https://github.com/pmndrs/use-gesture\n\n// wheel delta defaults from https://github.com/facebookarchive/fixed-data-table/blob/master/src/vendor_upstream/dom/normalizeWheel.js\nconst LINE_HEIGHT = 40;\nconst PAGE_HEIGHT = 800;\n\nexport function wheelValues(event: WheelEvent): Point {\n  let { deltaX, deltaY, deltaMode } = event;\n  // normalize wheel values, especially for Firefox\n  if (deltaMode === 1) {\n    deltaX *= LINE_HEIGHT;\n    deltaY *= LINE_HEIGHT;\n  } else if (deltaMode === 2) {\n    deltaX *= PAGE_HEIGHT;\n    deltaY *= PAGE_HEIGHT;\n  }\n  return { x: deltaX, y: deltaY };\n}\n","import { Rect, rectContainsPoint, Region } from \"@noya-app/noya-geometry\";\nimport { getPointHandles } from \"../utils/dragHandleUtils\";\nimport { isMoving } from \"../utils/isMoving\";\nimport {\n  DEFAULT_POINT_HANDLE_SIZE,\n  getAbsolutizeTransform,\n  IdentifiablePoint,\n} from \"../utils/pointUtils\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  PointHighlightableProperties,\n  PointProperties,\n  ScreenPointProperties,\n} from \"./contextProperties\";\nimport { NoneMode } from \"./PluginSystem\";\nimport { PointerData } from \"./pointerPlugin\";\n\ntype PointMode<StateSnapshot> =\n  | NoneMode\n  | {\n      type: \"movingPoint\";\n      region: Region;\n      snapshot: StateSnapshot;\n      id: string;\n    };\n\nexport type PointData = {\n  highlightedPointId?: string;\n  pointHandleSize: number;\n  zoom: number;\n} & Pick<PointerData, \"pointerDown\" | \"pointer\">;\n\ntype PointPluginOptions = {\n  pointHandleSize?: number;\n  movementThreshold?: number;\n  pointHandleHitSize?: number;\n};\n\ninterface PointContextProperties<StateSnapshot>\n  extends BaseContextProperties<PointMode<StateSnapshot>, PointData>,\n    ScreenPointProperties,\n    PointProperties,\n    PointHighlightableProperties {\n  getStateSnapshot: () => StateSnapshot;\n  getPoints: () => { points: IdentifiablePoint[]; rect: Rect } | undefined;\n  movePoint: (params: {\n    id: string;\n    region: Region;\n    snapshot: StateSnapshot;\n  }) => void;\n}\n\nexport function pointPlugin<StateSnapshot>(options: PointPluginOptions = {}) {\n  const {\n    pointHandleSize = DEFAULT_POINT_HANDLE_SIZE,\n    movementThreshold = 0,\n    pointHandleHitSize,\n  } = options;\n  const handleHitSize = pointHandleHitSize ?? pointHandleSize;\n\n  return createCanvasPlugin({\n    name: \"point\",\n    data: {\n      highlightedPointId: undefined,\n      pointHandleSize,\n      zoom: 1,\n    },\n    handlers: (context: PointContextProperties<StateSnapshot>) => ({\n      onPointerDown(event) {\n        if (context.getMode().type !== \"none\") return;\n\n        const data = context.getData();\n        const pointerDown = data.pointerDown;\n\n        if (!pointerDown) return;\n\n        const points = context.getPoints();\n        if (!points) return;\n        const pointHandles = getPointHandles({\n          points: points.points.map((point) =>\n            getAbsolutizeTransform(points.rect).applyTo(point)\n          ),\n          data: { ...data, pointHandleSize: handleHitSize },\n        });\n\n        const pointHandle = pointHandles.find((handle) =>\n          rectContainsPoint(handle.rect, pointerDown.anchor)\n        );\n\n        if (!pointHandle) return;\n        context.setMode({\n          type: \"movingPoint\",\n          region: pointerDown,\n          id: pointHandle.id,\n          snapshot: context.getStateSnapshot(),\n        });\n        event.preventDefault();\n      },\n      onPointerMove(event) {\n        const mode = context.getMode();\n        const data = context.getData();\n        const pointerDown = data.pointerDown;\n\n        if (mode.type === \"none\") {\n          if (!pointerDown) {\n            const point = context.getCanvasPoint(event.nativeEvent);\n            const points = context.filterPoints({\n              at: {\n                x: point.x - handleHitSize / 2,\n                y: point.y - handleHitSize / 2,\n                width: handleHitSize,\n                height: handleHitSize,\n              },\n              predicate: context.isPointHighlightable,\n            });\n            const firstPointId = points.length > 0 ? points[0].id : undefined;\n\n            if (firstPointId !== data.highlightedPointId) {\n              context.setData({ ...data, highlightedPointId: firstPointId });\n            }\n            return;\n          }\n          return;\n        }\n\n        if (mode.type === \"movingPoint\" && pointerDown) {\n          const shouldMove = isMoving(\n            pointerDown.anchor,\n            pointerDown.head,\n            data.zoom,\n            movementThreshold\n          );\n\n          if (shouldMove) {\n            context.movePoint({\n              id: mode.id,\n              region: pointerDown,\n              snapshot: mode.snapshot,\n            });\n\n            event.preventDefault();\n          }\n        }\n      },\n      onPointerUp(event) {\n        const mode = context.getMode();\n\n        if (mode.type === \"movingPoint\") {\n          context.setMode({ type: \"none\" });\n          event.preventDefault();\n        }\n      },\n      onPointerLeave() {\n        const mode = context.getMode();\n\n        if (mode.type !== \"none\") return;\n\n        const data = context.getData();\n\n        if (data.highlightedPointId) {\n          context.setData({ ...data, highlightedPointId: undefined });\n        }\n      },\n    }),\n  });\n}\n","import {\n  CompassDirection,\n  getCompassDirectionCursor,\n  getRegionDelta,\n  Point,\n  Rect,\n  rectContainsPoint,\n} from \"@noya-app/noya-geometry\";\nimport { getDragHandles } from \"../utils/dragHandleUtils\";\nimport { isMoving } from \"../utils/isMoving\";\nimport {\n  getScalingOptionsForEvent,\n  ScalingOptions,\n} from \"../utils/scalingUtils\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  ElementProperties,\n  ScalableProperties,\n} from \"./contextProperties\";\nimport { modeSwitch, NoneMode } from \"./PluginSystem\";\nimport { PointerData } from \"./pointerPlugin\";\n\nexport type ScaleMode<StateSnapshot> =\n  | NoneMode\n  | {\n      type: \"scaling\";\n      delta: Point;\n      snapshot: StateSnapshot;\n      direction: CompassDirection;\n      options: ScalingOptions;\n    };\n\nexport type ScaleData = {\n  zoom: number;\n  selectedElementIds: string[];\n  dragHandleSize: number;\n  hoveredDragHandleDirection?: CompassDirection;\n} & Pick<PointerData, \"pointerDown\" | \"pointer\">;\n\nexport type ScaleElementParameters<StateSnapshot> = {\n  elementIds: string[];\n  delta: Point;\n  snapshot: StateSnapshot;\n  direction: CompassDirection;\n  options: ScalingOptions;\n};\n\nexport interface ScaleContextProperties<CanvasElement, StateSnapshot>\n  extends BaseContextProperties<ScaleMode<StateSnapshot>, ScaleData>,\n    ElementProperties<CanvasElement>,\n    ScalableProperties<CanvasElement> {\n  getStateSnapshot: () => StateSnapshot;\n  adjustScaleDelta?: (\n    event: React.PointerEvent,\n    parameters: ScaleElementParameters<StateSnapshot>\n  ) => Point;\n  scaleElements: (parameters: ScaleElementParameters<StateSnapshot>) => void;\n  /**\n   * Returns the union of the selected elements' rects, in canvas coordinates (no transform).\n   */\n  getSelectionRect: () => Rect | undefined;\n  canScale?: () => boolean;\n}\n\nexport type ScalePluginOptions = {\n  movementThreshold?: number;\n  dragHandleSize?: number;\n};\n\nexport const DEFAULT_DRAG_HANDLE_SIZE = 8;\n\nexport function scalePlugin<CanvasElement, StateSnapshot>(\n  options: ScalePluginOptions = {}\n) {\n  const { movementThreshold = 0, dragHandleSize = DEFAULT_DRAG_HANDLE_SIZE } =\n    options;\n\n  return createCanvasPlugin({\n    name: \"scale\",\n    data: {\n      zoom: 1,\n      selectedElementIds: [],\n      dragHandleSize,\n    },\n    handlers: ({\n      getMode,\n      setMode,\n      getData,\n      setData,\n      adjustScaleDelta = (_, options) => options.delta,\n      canScale = () => true,\n      ...context\n    }: ScaleContextProperties<CanvasElement, StateSnapshot>) => ({\n      onPointerDown(event) {\n        if (!canScale()) return;\n\n        const data = getData();\n\n        if (getMode().type !== \"none\") return;\n        const pointerDown = data.pointerDown;\n\n        if (!pointerDown) return;\n\n        const selectionRect = context.getSelectionRect();\n\n        if (!selectionRect) return;\n\n        const dragHandles = getDragHandles({ selectionRect, data });\n\n        const dragHandle = dragHandles.find((handle) =>\n          rectContainsPoint(handle.rect, pointerDown.anchor)\n        );\n\n        if (dragHandle) {\n          event.preventDefault();\n        }\n      },\n      onPointerMove(event) {\n        if (!canScale()) return;\n\n        modeSwitch(getMode(), {\n          none: () => {\n            const selectionRect = context.getSelectionRect();\n\n            const data = getData();\n\n            if (!selectionRect) {\n              setData((data) => ({\n                ...data,\n                hoveredDragHandleDirection: undefined,\n              }));\n\n              return;\n            }\n\n            const dragHandles = getDragHandles({ selectionRect, data });\n\n            const pointerDown = data.pointerDown;\n            const pointer = data.pointer;\n\n            if (!pointerDown) {\n              const dragHandle = pointer\n                ? dragHandles.find((handle) =>\n                    rectContainsPoint(handle.rect, pointer)\n                  )\n                : undefined;\n\n              setData((data) => ({\n                ...data,\n                hoveredDragHandleDirection: dragHandle?.compassDirection,\n              }));\n\n              return;\n            }\n\n            const dragHandle = dragHandles.find((handle) =>\n              rectContainsPoint(handle.rect, pointerDown.anchor)\n            );\n\n            if (\n              dragHandle &&\n              isMoving(\n                pointerDown.anchor,\n                pointerDown.head,\n                data.zoom,\n                movementThreshold\n              )\n            ) {\n              const parameters: ScaleElementParameters<StateSnapshot> = {\n                elementIds: data.selectedElementIds,\n                delta: getRegionDelta(pointerDown),\n                snapshot: context.getStateSnapshot(),\n                direction: dragHandle.compassDirection,\n                options: getScalingOptionsForEvent(event),\n              };\n\n              const delta = adjustScaleDelta(event, parameters);\n\n              setMode({\n                type: \"scaling\",\n                delta,\n                snapshot: parameters.snapshot,\n                direction: parameters.direction,\n                options: parameters.options,\n              });\n\n              event.preventDefault();\n            }\n          },\n          scaling: ({ snapshot, direction }) => {\n            const data = getData();\n\n            if (!data.pointerDown) return;\n\n            const parameters: ScaleElementParameters<StateSnapshot> = {\n              elementIds: data.selectedElementIds,\n              delta: getRegionDelta(data.pointerDown),\n              snapshot,\n              direction,\n              options: getScalingOptionsForEvent(event),\n            };\n\n            const delta = adjustScaleDelta(event, parameters);\n\n            setMode({\n              type: \"scaling\",\n              delta,\n              snapshot,\n              direction,\n              options: parameters.options,\n            });\n\n            context.scaleElements?.({\n              ...parameters,\n              delta,\n            });\n\n            event.preventDefault();\n          },\n        });\n      },\n      onPointerUp(event) {\n        if (!canScale()) return;\n\n        const data = getData();\n\n        if (data.hoveredDragHandleDirection) {\n          const selectionRect = context.getSelectionRect();\n\n          const dragHandle = selectionRect\n            ? getDragHandles({ selectionRect, data }).find(\n                (handle) =>\n                  handle.compassDirection === data.hoveredDragHandleDirection\n              )\n            : undefined;\n\n          setData((data) => ({\n            ...data,\n            hoveredDragHandleDirection: dragHandle?.compassDirection,\n          }));\n        }\n\n        if (getMode().type !== \"scaling\") return;\n\n        setMode({ type: \"none\" });\n\n        event.preventDefault();\n      },\n    }),\n    getCursor: ({ data, mode }) => {\n      if (\n        (mode.type === \"none\" || mode.type === \"scaling\") &&\n        data.hoveredDragHandleDirection\n      ) {\n        return getCompassDirectionCursor(\n          data.hoveredDragHandleDirection,\n          \"bidirectional\"\n        );\n      }\n\n      return undefined;\n    },\n  });\n}\n","import {\n  AffineTransform,\n  CompassDirection,\n  createBounds,\n  getCompassDirectionAnchor,\n  getCompassDirectionUnitAnchor,\n  getOppositeCompassDirection,\n  getRegionDelta,\n  Point,\n  Rect,\n  Region,\n  Size,\n  unionRects,\n} from \"@noya-app/noya-geometry\";\nimport {\n  getBestSnapDelta,\n  getElementSnapDelta,\n  getGridSnapDelta,\n  getValuesOnAxis,\n} from \"./snapUtils\";\n\nexport type ScalingOriginMode = \"extent\" | \"center\";\n\nexport type ScalingOptions = {\n  preserveAspectRatio: boolean;\n  scalingOriginMode: ScalingOriginMode;\n  ignoreSnapping: boolean;\n};\n\nexport function getScalingOptionsForEvent({\n  shiftKey,\n  altKey,\n  ctrlKey,\n}: {\n  shiftKey: boolean;\n  altKey: boolean;\n  ctrlKey: boolean;\n}): ScalingOptions {\n  return {\n    preserveAspectRatio: shiftKey,\n    scalingOriginMode: altKey ? \"center\" : \"extent\",\n    ignoreSnapping: ctrlKey,\n  };\n}\n\n// This function doesn't ensure a positive width/height, since we use it when\n// scaling, which can result in a negative width/height.\nexport function getRectExtentPoint(rect: Rect, direction: CompassDirection) {\n  const minX = rect.x;\n  const minY = rect.y;\n  const maxX = rect.x + rect.width;\n  const maxY = rect.y + rect.height;\n  const midX = (maxX + minX) / 2;\n  const midY = (maxY + minY) / 2;\n\n  const x = direction.includes(\"w\")\n    ? minX\n    : direction.includes(\"e\")\n      ? maxX\n      : midX;\n\n  const y = direction.includes(\"n\")\n    ? minY\n    : direction.includes(\"s\")\n      ? maxY\n      : midY;\n\n  return { x, y };\n}\n\n/**\n * Resize a rect in a compass direction\n */\nexport function getScaleTransform(\n  rect: Rect,\n  delta: Point | Region,\n  direction: CompassDirection,\n  { scalingOriginMode, preserveAspectRatio }: ScalingOptions\n): AffineTransform {\n  if (\"anchor\" in delta) {\n    delta = getRegionDelta(delta);\n  }\n\n  const oppositeDirection = getOppositeCompassDirection(direction);\n\n  const extent = getRectExtentPoint(rect, direction);\n  const oppositeExtent = getRectExtentPoint(rect, oppositeDirection);\n\n  if (scalingOriginMode === \"center\") {\n    delta = {\n      x: delta.x * 2,\n      y: delta.y * 2,\n    };\n  }\n\n  const newExtent = { x: extent.x + delta.x, y: extent.y + delta.y };\n\n  const anchor = getCompassDirectionUnitAnchor(direction);\n\n  const multiplier = {\n    x: anchor.x * 2 - 1,\n    y: anchor.y * 2 - 1,\n  };\n\n  const newSize = {\n    width: newExtent.x - oppositeExtent.x,\n    height: newExtent.y - oppositeExtent.y,\n  };\n\n  const scaleX = (multiplier.x * newSize.width) / rect.width;\n  const scaleY = (multiplier.y * newSize.height) / rect.height;\n\n  const largestMagnitude =\n    Math.abs(scaleX) > Math.abs(scaleY) ? scaleX : scaleY;\n\n  const scale = preserveAspectRatio\n    ? { x: largestMagnitude, y: largestMagnitude }\n    : {\n        x: extent.x === oppositeExtent.x ? 1 : scaleX,\n        y: extent.y === oppositeExtent.y ? 1 : scaleY,\n      };\n\n  // Adjust the sign of the scale:\n  // - If scaling along a single axis, ensure a positive sign so we don't flip along the opposite axis\n  // - If scaling opposite corners, ensure the rect remains in the correct quadrant\n  if (extent.y === oppositeExtent.y) {\n    scale.y = Math.abs(scale.y);\n  } else if (Math.sign(scale.y) !== Math.sign(scaleY)) {\n    scale.y *= -1;\n  }\n\n  if (extent.x === oppositeExtent.x) {\n    scale.x = Math.abs(scale.x);\n  } else if (Math.sign(scale.x) !== Math.sign(scaleX)) {\n    scale.x *= -1;\n  }\n\n  switch (scalingOriginMode) {\n    case \"extent\": {\n      return AffineTransform.scale(scale.x, scale.y, oppositeExtent);\n    }\n    case \"center\": {\n      const bounds = createBounds(rect);\n\n      return AffineTransform.scale(scale.x, scale.y, {\n        x: bounds.midX,\n        y: bounds.midY,\n      });\n    }\n  }\n}\n\nexport function getScaleSnapDelta({\n  movingRects,\n  stationaryRects,\n  delta,\n  direction,\n  gridSize,\n}: {\n  movingRects: Rect[];\n  stationaryRects: Rect[];\n  delta: Point;\n  direction: CompassDirection;\n  gridSize: Size;\n}): Point {\n  const movingBoundingBox = unionRects(...movingRects);\n\n  const anchor = getCompassDirectionAnchor(direction, movingBoundingBox);\n\n  const possibleSnapsX = [\n    getElementSnapDelta({\n      movingValues: [anchor.x + delta.x],\n      stationaryValues: getValuesOnAxis(stationaryRects, \"x\"),\n    }),\n    getGridSnapDelta({\n      value: anchor.x + delta.x,\n      gridSize: gridSize.width,\n    }),\n  ];\n\n  const possibleSnapsY = [\n    getElementSnapDelta({\n      movingValues: [anchor.y + delta.y],\n      stationaryValues: getValuesOnAxis(stationaryRects, \"y\"),\n    }),\n    getGridSnapDelta({\n      value: anchor.y + delta.y,\n      gridSize: gridSize.height,\n    }),\n  ];\n\n  const snapDelta = {\n    x: getBestSnapDelta(possibleSnapsX),\n    y: getBestSnapDelta(possibleSnapsY),\n  };\n\n  return {\n    x: delta.x + snapDelta.x,\n    y: delta.y + snapDelta.y,\n  };\n}\n","import { updateSelectionWithItem } from \"../utils/selectionUtils\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  ElementProperties,\n  PointerCaptureProperties,\n  ScreenPointProperties,\n  SelectableProperties,\n} from \"./contextProperties\";\nimport { NoneMode } from \"./PluginSystem\";\n\nexport type SelectMode = NoneMode;\n\nexport type SelectData = {\n  selectedElementIds: string[];\n};\n\nexport interface SelectContextProperties<CanvasElement>\n  extends BaseContextProperties<SelectMode, SelectData>,\n    ScreenPointProperties,\n    ElementProperties<CanvasElement>,\n    SelectableProperties<CanvasElement>,\n    PointerCaptureProperties {}\n\nexport function selectPlugin<CanvasElement>() {\n  return createCanvasPlugin({\n    name: \"select\",\n    data: {\n      selectedElementIds: [],\n    },\n    handlers: (context: SelectContextProperties<CanvasElement>) => ({\n      onPointerDown(event) {\n        const mode = context.getMode();\n\n        if (mode.type !== \"none\") return;\n\n        // if (isRightButtonClicked(event)) return;\n\n        const data = context.getData();\n        const point = context.getCanvasPoint(event.nativeEvent);\n        const elements = context.filterElements({\n          at: point,\n          predicate: context.isSelectable,\n        });\n        const elementId =\n          elements.length > 0 ? context.getElementId(elements[0]) : undefined;\n        const selection = updateSelectionWithItem(\n          data.selectedElementIds,\n          elementId,\n          event.shiftKey\n        );\n\n        if (selection !== data.selectedElementIds) {\n          context.setData({ ...data, selectedElementIds: selection });\n        }\n      },\n    }),\n  });\n}\n","import {\n  AffineTransform,\n  Point,\n  Rect,\n  Size,\n  roundPoint,\n} from \"@noya-app/noya-geometry\";\nimport { clamp } from \"@noya-app/noya-utils\";\nimport { Dispatch, SetStateAction } from \"react\";\nimport { Easing, animateValue } from \"../utils/animationUtils\";\nimport { wheelValues } from \"../utils/wheelUtils\";\nimport { Zoom, ZoomRange } from \"../utils/zoomUtils\";\nimport { createCanvasPlugin } from \"./baseCanvas\";\nimport {\n  BaseContextProperties,\n  HandleKeyboardEventProperties,\n} from \"./contextProperties\";\nimport { NoneMode } from \"./PluginSystem\";\n\nexport type ZoomMode = NoneMode;\n\nexport type ZoomData = {\n  zoom: number;\n  size: Size;\n  origin: Point;\n};\n\nexport interface ZoomContextProperties\n  extends BaseContextProperties<ZoomMode, ZoomData>,\n    HandleKeyboardEventProperties {}\n\nexport type ZoomPluginOptions = {\n  range?: [number, number];\n  onWheelShouldPreventDefault?: boolean;\n  /** @default 0.02 */\n  scaleFactor?: number;\n};\n\nexport function zoomPlugin(options: ZoomPluginOptions = {}) {\n  const {\n    range = [Zoom.min, Zoom.max],\n    onWheelShouldPreventDefault = false,\n    scaleFactor = 0.02,\n  } = options;\n\n  return createCanvasPlugin({\n    name: \"zoom\",\n    data: {\n      zoom: 1,\n      size: { width: 0, height: 0 },\n      origin: { x: 0, y: 0 },\n    },\n    handlers: ({\n      handleKeyboardEvent,\n      getData,\n      setData,\n    }: ZoomContextProperties) => ({\n      onWheel: (event) => {\n        if (!(event.metaKey || event.ctrlKey)) return;\n\n        const data = getData();\n        const delta = wheelValues(event.nativeEvent);\n        const zoomFactor = 1 - delta.y * scaleFactor;\n\n        const newZoom = setZoom(data, zoomFactor, range, \"multiply\");\n\n        setData(newZoom);\n\n        if (onWheelShouldPreventDefault) {\n          event.preventDefault();\n        }\n      },\n      onKeyDown: (event) => {\n        handleKeyboardEvent({\n          \"Mod-=\": () => setData(zoomIn(getData(), range)),\n          \"Mod--\": () => setData(zoomOut(getData(), range)),\n          \"Mod-0\": () => setData(zoom0(getData(), range)),\n        })(event);\n      },\n    }),\n  });\n}\n\nexport function setZoom<Data extends ZoomData>(\n  data: Data,\n  value: number,\n  range: ZoomRange,\n  mode?: \"replace\" | \"multiply\" | \"multiplyDiscrete\"\n): Data {\n  const { size, origin, zoom } = data;\n\n  let newZoom;\n\n  switch (mode) {\n    case \"multiplyDiscrete\":\n      newZoom = Zoom.clamp(Zoom.nearestLevel(value * zoom));\n      break;\n    case \"multiply\":\n      newZoom = Zoom.clamp(value * zoom);\n      break;\n    default:\n      newZoom = Zoom.clamp(value);\n  }\n\n  newZoom = clamp(newZoom, range[0], range[1]);\n\n  const viewportCenter = {\n    x: size.width / 2,\n    y: size.height / 2,\n  };\n\n  // To find the new scrollOrigin: start at the viewport center and\n  // move by the scaled the distance to the scrollOrigin\n  const newOrigin = roundPoint(\n    AffineTransform.translate(\n      (origin.x - viewportCenter.x) * (newZoom / zoom),\n      (origin.y - viewportCenter.y) * (newZoom / zoom)\n    ).applyTo(viewportCenter)\n  );\n\n  return {\n    ...data,\n    zoom: newZoom,\n    origin: newOrigin,\n  };\n}\n\nexport function zoomIn<Data extends ZoomData>(\n  data: Data,\n  range: ZoomRange\n): Data {\n  return setZoom(data, 2, range, \"multiplyDiscrete\");\n}\n\nexport function zoomOut<Data extends ZoomData>(\n  data: Data,\n  range: ZoomRange\n): Data {\n  return setZoom(data, 0.5, range, \"multiplyDiscrete\");\n}\n\nexport function zoom0<Data extends ZoomData>(\n  data: Data,\n  range: ZoomRange\n): Data {\n  return setZoom(data, 1, range, \"replace\");\n}\n\nexport type ZoomAnimatedOptions<Data extends ZoomData> = {\n  zoom: number;\n  range: ZoomRange;\n  setData: Dispatch<SetStateAction<Data>>;\n  duration?: number;\n  easing?: (progress: number) => number;\n};\n\nexport const defaultZoomAnimationDuration = 150;\nexport const defaultZoomAnimationEasing = Easing.easeInOut;\n\nexport function zoomInAnimated<Data extends ZoomData>({\n  zoom,\n  range,\n  setData,\n  duration = defaultZoomAnimationDuration,\n  easing = defaultZoomAnimationEasing,\n}: ZoomAnimatedOptions<Data>) {\n  animateValue({\n    start: zoom,\n    end: Zoom.nearestLevel(zoom * 2),\n    duration,\n    easing,\n    onChange: (value) => {\n      setData((data) => setZoom(data, value, range));\n    },\n  });\n}\n\nexport function zoomOutAnimated<Data extends ZoomData>({\n  zoom,\n  range,\n  setData,\n  duration = defaultZoomAnimationDuration,\n  easing = defaultZoomAnimationEasing,\n}: ZoomAnimatedOptions<Data>) {\n  animateValue({\n    start: zoom,\n    end: Zoom.nearestLevel(zoom * 0.5),\n    duration,\n    easing,\n    onChange: (value) => {\n      setData((data) => setZoom(data, value, range));\n    },\n  });\n}\n\nexport function zoom0Animated<Data extends ZoomData>({\n  zoom,\n  range,\n  setData,\n  duration = defaultZoomAnimationDuration,\n  easing = defaultZoomAnimationEasing,\n}: ZoomAnimatedOptions<Data>) {\n  animateValue({\n    start: zoom,\n    end: 1,\n    duration,\n    easing,\n    onChange: (value) => {\n      setData((data) => setZoom(data, value, range));\n    },\n  });\n}\n\nexport function zoomToFit<Data extends ZoomData>({\n  data,\n  rect,\n  range,\n  padding = 0,\n}: {\n  data: Data;\n  rect: Rect;\n  range?: ZoomRange;\n  padding?: number;\n}): Data {\n  const paddedCanvasSize = {\n    width: data.size.width - padding * 2,\n    height: data.size.height - padding * 2,\n  };\n\n  let zoom = Math.min(\n    paddedCanvasSize.width / rect.width,\n    paddedCanvasSize.height / rect.height\n  );\n\n  if (range) {\n    zoom = clamp(zoom, range[0], range[1]);\n  }\n\n  // Center the rect within the padded canvas area\n  const origin = {\n    x: paddedCanvasSize.width / 2 + padding - (rect.x + rect.width / 2) * zoom,\n    y:\n      paddedCanvasSize.height / 2 + padding - (rect.y + rect.height / 2) * zoom,\n  };\n\n  return { ...data, zoom, origin };\n}\n\nexport function zoomToFitAnimated<Data extends ZoomData>({\n  data,\n  rect,\n  padding,\n  range,\n  duration = defaultZoomAnimationDuration,\n  easing = defaultZoomAnimationEasing,\n  setData,\n}: {\n  data: Data;\n  rect: Rect;\n  padding?: number;\n  range: ZoomRange;\n  duration?: number;\n  easing?: (progress: number) => number;\n  setData: Dispatch<SetStateAction<Data>>;\n}): void {\n  const newData = zoomToFit({ data, rect, range, padding });\n\n  animateValue({\n    start: data.zoom,\n    end: newData.zoom,\n    duration,\n    easing,\n    onChange: (value) => {\n      setData((data) => ({ ...data, zoom: value }));\n    },\n  });\n\n  animateValue({\n    start: data.origin.x,\n    end: newData.origin.x,\n    duration,\n    easing,\n    onChange: (value) => {\n      setData((data) => ({ ...data, origin: { ...data.origin, x: value } }));\n    },\n  });\n\n  animateValue({\n    start: data.origin.y,\n    end: newData.origin.y,\n    duration,\n    easing,\n    onChange: (value) => {\n      setData((data) => ({ ...data, origin: { ...data.origin, y: value } }));\n    },\n  });\n}\n","import { CubicCoeff } from \"@noya-app/noya-geometry\";\nimport { lerp } from \"@noya-app/noya-utils\";\n\nconst EaseInOut: CubicCoeff = CubicCoeff.fromCubic({\n  P0: { x: 0, y: 0 },\n  P1: { x: 0.25, y: 0 },\n  P2: { x: 0.75, y: 1 },\n  P3: { x: 1, y: 1 },\n});\n\nfunction easeInOut(progress: number) {\n  return EaseInOut.eval(progress).y;\n}\n\nfunction linear(progress: number) {\n  return progress;\n}\n\nexport const Easing = {\n  easeInOut,\n  linear,\n};\n\nexport function animateValue({\n  start,\n  end,\n  duration,\n  easing = linear,\n  onChange,\n}: {\n  start: number;\n  end: number;\n  duration: number;\n  easing?: (progress: number) => number;\n  onChange: (value: number) => void;\n}) {\n  const startTime = performance.now();\n  let animationFrame: number;\n\n  function runAnimation() {\n    const currentTime = performance.now();\n    const progress = Math.min((currentTime - startTime) / duration, 1);\n    const value = lerp(start, end, easing(progress));\n    onChange(value);\n\n    if (progress < 1) {\n      animationFrame = requestAnimationFrame(runAnimation);\n    }\n  }\n\n  runAnimation();\n\n  return () => {\n    if (animationFrame) {\n      cancelAnimationFrame(animationFrame);\n    }\n  };\n}\n","import { clamp } from \"@noya-app/noya-utils\";\n\nconst ZOOM_LEVELS = [\n  0.015625, 0.03125, 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64, 128, 256,\n];\n\nexport type ZoomRange = [number, number];\n\nfunction nearestLevel(zoom: number) {\n  return ZOOM_LEVELS.reduce((prev, curr) =>\n    Math.abs(curr - zoom) < Math.abs(prev - zoom) ? curr : prev\n  );\n}\n\nconst min = ZOOM_LEVELS[0];\nconst max = ZOOM_LEVELS[ZOOM_LEVELS.length - 1];\n\nexport const Zoom = {\n  min,\n  max,\n  range: [min, max] satisfies ZoomRange,\n  nearestLevel,\n  clamp: (zoom: number) => clamp(zoom, Zoom.min, Zoom.max),\n};\n","import {\n  AffineTransform,\n  normalizeRect,\n  Point,\n  Rect,\n  rectContainsPoint,\n  rectsIntersect,\n  Size,\n  unionRects,\n} from \"@noya-app/noya-geometry\";\nimport { zip } from \"@noya-app/noya-utils\";\nimport { GetElementsOptions } from \"../plugins/contextProperties\";\n\nexport function filterElements<CanvasElement extends { rect: Rect }>(\n  elements: CanvasElement[],\n  options: GetElementsOptions<CanvasElement>\n): CanvasElement[];\nexport function filterElements<CanvasElement>(\n  elements: CanvasElement[],\n  getRect: (element: CanvasElement) => Rect,\n  options: GetElementsOptions<CanvasElement>\n): CanvasElement[];\nexport function filterElements<CanvasElement extends { rect: Rect }>(\n  ...args:\n    | [CanvasElement[], GetElementsOptions<CanvasElement>]\n    | [\n        CanvasElement[],\n        (element: CanvasElement) => Rect,\n        GetElementsOptions<CanvasElement>,\n      ]\n): CanvasElement[] {\n  let [elements, getRect, options] =\n    args.length === 2\n      ? [args[0], (element: CanvasElement) => element.rect, args[1]]\n      : [args[0], args[1], args[2]];\n\n  elements = elements.toReversed();\n\n  if (options.predicate) {\n    elements = elements.filter(options.predicate);\n  }\n\n  const elementsWithRects = zip(elements, elements.map(getRect));\n\n  if (options.at) {\n    if (\"width\" in options.at) {\n      const at = options.at;\n      elements = elementsWithRects\n        .filter(([_, rect]) => rectsIntersect(rect, at))\n        .map(([element]) => element);\n    } else {\n      const at = options.at;\n      elements = elementsWithRects\n        .filter(([_, rect]) => rectContainsPoint(rect, at))\n        .map(([element]) => element);\n    }\n  }\n\n  return elements;\n}\n\nfunction normalizeSize(size: Size | number | false): Size {\n  if (size === false) size = 0;\n  if (typeof size === \"number\") size = { width: size, height: size };\n  return size;\n}\n\ninterface Dimension {\n  newValue: number;\n  minSize: number;\n}\n\n/**\n * Updates a single dimension (width or height) with element and grid snapping\n */\nfunction snapDimension({ newValue, minSize }: Dimension): number {\n  return minSize === 0 ? newValue : Math.max(newValue, minSize);\n}\n\n/**\n * Calculates dimensions while maintaining aspect ratio\n */\nfunction getDimensionsWithAspectRatio({\n  size,\n  originalAspectRatio,\n  minSize,\n}: {\n  size: Size;\n  originalAspectRatio: number;\n  minSize: Size;\n}): Size {\n  const newAspectRatio = size.width / size.height;\n\n  let width = size.width;\n  let height = size.height;\n\n  // Adjust dimensions to maintain aspect ratio\n  if (newAspectRatio > originalAspectRatio) {\n    width = height * originalAspectRatio;\n  } else {\n    height = width / originalAspectRatio;\n  }\n\n  // Re-apply minimum size constraints\n  if (width < minSize.width) {\n    width = minSize.width;\n    height = width / originalAspectRatio;\n  }\n  if (height < minSize.height) {\n    height = minSize.height;\n    width = height * originalAspectRatio;\n  }\n\n  return { width, height };\n}\n\ntype TransformDraftElementsOptions<CanvasElement extends { id: string }> = {\n  draftElements: CanvasElement[];\n  snapshotElements: CanvasElement[];\n  transform: AffineTransform;\n  minimumElementSize?: Size | number | false;\n  preserveAspectRatio?: boolean;\n  normalizeNegativeScale?: boolean;\n};\n\ntype TransformableElementOptions<CanvasElement> = {\n  updateElement: (\n    element: CanvasElement,\n    newProps: { rect: Rect; flip: { x: boolean; y: boolean } }\n  ) => void;\n  getRect: (element: CanvasElement) => Rect;\n};\n\nexport function transformDraftElements<CanvasElement extends { id: string }>(\n  options: TransformDraftElementsOptions<CanvasElement> &\n    TransformableElementOptions<CanvasElement>\n): void;\nexport function transformDraftElements<\n  CanvasElement extends { id: string; rect: Rect },\n>(options: TransformDraftElementsOptions<CanvasElement>): void;\nexport function transformDraftElements<CanvasElement extends { id: string }>({\n  draftElements,\n  snapshotElements,\n  transform,\n  minimumElementSize = 1,\n  preserveAspectRatio = false,\n  normalizeNegativeScale = true,\n  getRect = (element) => {\n    if (\"rect\" in element) {\n      return element.rect as Rect;\n    }\n    return { x: 0, y: 0, width: 0, height: 0 };\n  },\n  updateElement = (element, newProps) => {\n    if (\"rect\" in element) {\n      element.rect = newProps.rect;\n    }\n  },\n}: TransformDraftElementsOptions<CanvasElement> &\n  Partial<TransformableElementOptions<CanvasElement>>): void {\n  const minSize = normalizeSize(minimumElementSize);\n\n  // Get scale components to check for negative scaling\n  const { x: scaleX, y: scaleY } = transform.scaleComponents;\n  const hasNegativeScaleX = scaleX < 0;\n  const hasNegativeScaleY = scaleY < 0;\n  const hasNegativeScale = hasNegativeScaleX || hasNegativeScaleY;\n  const isScaling = scaleX !== 1 || scaleY !== 1;\n  const flip = { x: hasNegativeScaleX, y: hasNegativeScaleY };\n\n  if (hasNegativeScale && !normalizeNegativeScale) {\n    // Prevent negative scaling by using absolute values\n    const fixedTransform = AffineTransform.translate(\n      transform.tx,\n      transform.ty\n    ).scale(Math.abs(scaleX), Math.abs(scaleY));\n    transform = fixedTransform;\n  }\n\n  draftElements.forEach((draftElement) => {\n    const snapshotElement = snapshotElements.find(\n      (snapshotElement) => snapshotElement.id === draftElement.id\n    );\n\n    if (snapshotElement) {\n      let resultRect = { ...getRect(snapshotElement) };\n\n      let newRect = transform.applyTo(getRect(snapshotElement));\n\n      // Normalize the rect if we have negative scaling\n      if (hasNegativeScale && normalizeNegativeScale) {\n        newRect = normalizeRect(newRect);\n      }\n\n      // Update position\n      resultRect.x = newRect.x;\n      resultRect.y = newRect.y;\n\n      if (!isScaling) {\n        updateElement(draftElement, {\n          rect: resultRect,\n          flip,\n        });\n\n        return;\n      }\n\n      // Update dimensions\n      let size: Size = {\n        width: Math.max(newRect.width, minSize.width),\n        height: Math.max(newRect.height, minSize.height),\n      };\n\n      if (preserveAspectRatio) {\n        // Use absolute values for aspect ratio calculation since we've already normalized\n        const originalAspectRatio = Math.abs(\n          getRect(snapshotElement).width / getRect(snapshotElement).height\n        );\n\n        // Maintain aspect ratio while respecting minimum size\n        size = getDimensionsWithAspectRatio({\n          size,\n          originalAspectRatio,\n          minSize,\n        });\n      } else {\n        // If not maintaining aspect ratio, snap dimensions independently\n        size = {\n          width: snapDimension({\n            newValue: size.width,\n            minSize: minSize.width,\n          }),\n          height: snapDimension({\n            newValue: size.height,\n            minSize: minSize.height,\n          }),\n        };\n      }\n\n      resultRect.width = size.width;\n      resultRect.height = size.height;\n\n      updateElement(draftElement, {\n        rect: resultRect,\n        flip,\n      });\n    }\n  });\n}\n\nexport function getSelectionRect<CanvasElement extends { rect: Rect }>(\n  elements: CanvasElement[]\n): Rect | undefined;\nexport function getSelectionRect<CanvasElement>(\n  elements: CanvasElement[],\n  getRect: (element: CanvasElement) => Rect\n): Rect | undefined;\nexport function getSelectionRect<CanvasElement extends { rect: Rect }>(\n  ...args:\n    | [CanvasElement[]]\n    | [CanvasElement[], (element: CanvasElement) => Rect]\n): Rect | undefined {\n  const [elements, getRect] = args;\n\n  if (elements.length === 0) {\n    return undefined;\n  }\n\n  const rects = getRect\n    ? elements.map(getRect)\n    : elements.map((element) => element.rect);\n\n  return unionRects(...rects.filter(Boolean));\n}\n\nexport function applyFlip<P extends Point>(\n  point: P,\n  flip: { x: boolean; y: boolean }\n): P {\n  return AffineTransform.scale(flip.x ? -1 : 1, flip.y ? -1 : 1, {\n    x: 0.5,\n    y: 0.5,\n  }).applyTo(point);\n}\n","import {\n  BoundsKeyX,\n  BoundsKeyY,\n  createResizeTransform,\n  CreateResizeTransformOptions,\n  Point,\n} from \"@noya-app/noya-geometry\";\n\nimport { getResizePositionForBounds } from \"@noya-app/noya-geometry\";\n\nimport { Rect } from \"@noya-app/noya-geometry\";\nimport { BaseCanvasData, getCanvasTransform } from \"../plugins/baseCanvas\";\n\ntype GetViewportOriginOptions = {\n  data: BaseCanvasData;\n  rect: Rect;\n  /** percentage of overlap to consider as \"within viewport\" */\n  overlapThreshold?: number;\n} & Omit<CreateResizeTransformOptions, \"resizePosition\">;\n\ntype SingleAxisLineSegment = [number, number];\n\nfunction calculateLineOverlap(\n  line1: SingleAxisLineSegment,\n  line2: SingleAxisLineSegment\n) {\n  const [start1, end1] = line1;\n  const [start2, end2] = line2;\n\n  const overlap = Math.min(end1, end2) - Math.max(start1, start2);\n  return overlap;\n}\n\nexport function getViewportOriginContainingRect({\n  data,\n  rect: rectToContain,\n  overlapThreshold = 1,\n  ...options\n}: GetViewportOriginOptions) {\n  const { x: xOverlapFraction, y: yOverlapFraction } = getRectOverlapFraction({\n    data,\n    rect: rectToContain,\n  });\n\n  const canvasCenterPoint = {\n    x: data.size.width / 2,\n    y: data.size.height / 2,\n  };\n\n  const newRectCenterPoint = {\n    x: rectToContain.x + rectToContain.width / 2,\n    y: rectToContain.y + rectToContain.height / 2,\n  };\n\n  const originTransform = getCanvasTransform(data);\n  const translatedRectCenterPoint = originTransform.applyTo(newRectCenterPoint);\n\n  const xAnchor: BoundsKeyX =\n    translatedRectCenterPoint.x < canvasCenterPoint.x ? \"minX\" : \"maxX\";\n  const yAnchor: BoundsKeyY =\n    translatedRectCenterPoint.y < canvasCenterPoint.y ? \"minY\" : \"maxY\";\n  const resizePosition = getResizePositionForBounds({\n    x: xAnchor,\n    y: yAnchor,\n  });\n\n  const transform = createResizeTransform(rectToContain, data.size, {\n    ...options,\n    resizePosition,\n  });\n\n  return {\n    x: xOverlapFraction < overlapThreshold ? transform.tx : data.origin.x,\n    y: yOverlapFraction < overlapThreshold ? transform.ty : data.origin.y,\n  };\n}\n\nexport function isRectInViewport({\n  data,\n  rect: rectToContain,\n  fractionOfRectVisible = 1,\n}: {\n  data: BaseCanvasData;\n  rect: Rect;\n  fractionOfRectVisible?: number;\n}) {\n  const { x: xOverlapFraction, y: yOverlapFraction } = getRectOverlapFraction({\n    data,\n    rect: rectToContain,\n  });\n  return (\n    xOverlapFraction >= fractionOfRectVisible &&\n    yOverlapFraction >= fractionOfRectVisible\n  );\n}\n\nfunction getRectOverlapFraction({\n  data,\n  rect: rectToContain,\n}: {\n  data: BaseCanvasData;\n  rect: Rect;\n}): Point {\n  const originTransform = getCanvasTransform(data);\n  const translatedRect = originTransform.applyTo(rectToContain);\n\n  const xOverlap = calculateLineOverlap(\n    [translatedRect.x, translatedRect.x + translatedRect.width],\n    [0, data.size.width]\n  );\n  const xOverlapFraction = xOverlap / translatedRect.width;\n\n  const yOverlap = calculateLineOverlap(\n    [translatedRect.y, translatedRect.y + translatedRect.height],\n    [0, data.size.height]\n  );\n  const yOverlapFraction = yOverlap / translatedRect.height;\n\n  return {\n    x: xOverlapFraction,\n    y: yOverlapFraction,\n  };\n}\n"],"mappings":"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","names":["React","useMemo","isDeepEqual","assignRef","React","forwardRef","useCallback","useEffect","useMemo","useRef","useMemo","InfiniteCanvas","useMemo","Placeholder","AffineTransform","handlers","React","forwardRef","useRef","useMemo","useEffect","data","useCallback","getData","setData","isDeepEqual","assignRef","ReactCanvas","useMemo","React","Group","Rectangle","React","useMemo","distance","ReactCanvas","useMemo","getHandleRect","React","Group","Rectangle","createRect","insetRect","Rectangle","React","useMemo","ReactCanvas","useMemo","React","Rectangle","insetRect","createRect","insetRect","Group","Rectangle","React","useMemo","ReactCanvas","useMemo","React","Group","insetRect","Rectangle","insetRect","Rectangle","React","useMemo","ReactCanvas","useMemo","React","Rectangle","insetRect","Polyline","React","ReactCanvas","React","Polyline","distance","useCallback","useRef","rectContainsPoint","data","rectContainsPoint","data","min","max","clamp01","rectContainsPoint","rectContainsPoint","getRegionDelta","AffineTransform","unionRects","AffineTransform","unionRects","options","getRegionDelta","data","rectContainsPoint","rectContainsPoint","getRegionDelta","rectContainsPoint","AffineTransform","createBounds","getCompassDirectionAnchor","getRegionDelta","unionRects","getRegionDelta","AffineTransform","createBounds","unionRects","getCompassDirectionAnchor","options","rectContainsPoint","data","dragHandle","getRegionDelta","AffineTransform","roundPoint","clamp","clamp","handleKeyboardEvent","clamp","roundPoint","AffineTransform","data","AffineTransform","rectContainsPoint","unionRects","snapshotElement"]}