"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.SelectedOutlineOverlay = exports.orderOutlinesForRendering = exports.selectedOutlineDragThresholdPx = exports.getTransformedSvgViewportPoints = exports.getSequencesWithSelectableOutlines = exports.getSelectedSequenceKeys = exports.getSelectedOutlineRotationPivot = exports.getSelectedOutlineRotationDeltaDegrees = exports.getSelectedOutlineRotationCornerInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getOutlineSelectionInteraction = exports.getOutlineDoubleClickAction = exports.snapSelectedOutlineUv = exports.snapSelectedOutlineTransformOriginUv = exports.snapSelectedOutlineRotationDeltaDegrees = exports.selectedOutlineUvSnapThresholdPx = exports.selectedOutlineTransformOriginSnapThresholdPx = exports.isSelectedOutlineDragPastThreshold = exports.getSelectedOutlineTransformOriginLockedAxis = exports.getSelectedOutlineScaleEdgeInfo = exports.getSelectedOutlineScaleDragValues = exports.getSelectedOutlineScaleDragStates = exports.getSelectedOutlineScaleDragChanges = exports.getSelectedOutlineRotationDragValues = exports.getSelectedOutlineRotationDragStates = exports.getSelectedOutlineRotationDragChanges = exports.getSelectedOutlineKeyboardNudgeDeltas = exports.getSelectedOutlineKeyboardNudgeDelta = exports.getSelectedOutlineDragValues = exports.getSelectedOutlineDragChanges = exports.getSelectedOutlineActiveSchema = exports.compensateTranslateForTransformOrigin = exports.applySelectedOutlineTransformOriginAxisLock = exports.applySelectedOutlineDragAxisLock = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const player_1 = require("@remotion/player");
const react_1 = __importStar(require("react"));
const remotion_1 = require("remotion");
const no_react_1 = require("remotion/no-react");
const client_id_1 = require("../helpers/client-id");
const interactivity_enabled_1 = require("../helpers/interactivity-enabled");
const use_keybinding_1 = require("../helpers/use-keybinding");
const editor_guides_1 = require("../state/editor-guides");
const editor_outlines_1 = require("../state/editor-outlines");
const scale_lock_1 = require("../state/scale-lock");
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
const selected_outline_drag_1 = require("./selected-outline-drag");
const selected_outline_measurement_1 = require("./selected-outline-measurement");
const selected_outline_snap_1 = require("./selected-outline-snap");
const selected_outline_types_1 = require("./selected-outline-types");
const selected_outline_uv_1 = require("./selected-outline-uv");
const SelectedOutlineElement_1 = require("./SelectedOutlineElement");
const SelectedOutlineUvControls_1 = require("./SelectedOutlineUvControls");
const call_add_keyframe_1 = require("./Timeline/call-add-keyframe");
const imperative_state_1 = require("./Timeline/imperative-state");
const save_sequence_prop_1 = require("./Timeline/save-sequence-prop");
const timeline_scroll_logic_1 = require("./Timeline/timeline-scroll-logic");
const TimelineSelection_1 = require("./Timeline/TimelineSelection");
const selected_outline_drag_2 = require("./selected-outline-drag");
Object.defineProperty(exports, "applySelectedOutlineDragAxisLock", { enumerable: true, get: function () { return selected_outline_drag_2.applySelectedOutlineDragAxisLock; } });
Object.defineProperty(exports, "applySelectedOutlineTransformOriginAxisLock", { enumerable: true, get: function () { return selected_outline_drag_2.applySelectedOutlineTransformOriginAxisLock; } });
Object.defineProperty(exports, "compensateTranslateForTransformOrigin", { enumerable: true, get: function () { return selected_outline_drag_2.compensateTranslateForTransformOrigin; } });
Object.defineProperty(exports, "getSelectedOutlineActiveSchema", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineActiveSchema; } });
Object.defineProperty(exports, "getSelectedOutlineDragChanges", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineDragChanges; } });
Object.defineProperty(exports, "getSelectedOutlineDragValues", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineDragValues; } });
Object.defineProperty(exports, "getSelectedOutlineKeyboardNudgeDelta", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineKeyboardNudgeDelta; } });
Object.defineProperty(exports, "getSelectedOutlineKeyboardNudgeDeltas", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineKeyboardNudgeDeltas; } });
Object.defineProperty(exports, "getSelectedOutlineRotationDragChanges", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineRotationDragChanges; } });
Object.defineProperty(exports, "getSelectedOutlineRotationDragStates", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineRotationDragStates; } });
Object.defineProperty(exports, "getSelectedOutlineRotationDragValues", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineRotationDragValues; } });
Object.defineProperty(exports, "getSelectedOutlineScaleDragChanges", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineScaleDragChanges; } });
Object.defineProperty(exports, "getSelectedOutlineScaleDragStates", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineScaleDragStates; } });
Object.defineProperty(exports, "getSelectedOutlineScaleDragValues", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineScaleDragValues; } });
Object.defineProperty(exports, "getSelectedOutlineScaleEdgeInfo", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineScaleEdgeInfo; } });
Object.defineProperty(exports, "getSelectedOutlineTransformOriginLockedAxis", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineTransformOriginLockedAxis; } });
Object.defineProperty(exports, "isSelectedOutlineDragPastThreshold", { enumerable: true, get: function () { return selected_outline_drag_2.isSelectedOutlineDragPastThreshold; } });
Object.defineProperty(exports, "selectedOutlineTransformOriginSnapThresholdPx", { enumerable: true, get: function () { return selected_outline_drag_2.selectedOutlineTransformOriginSnapThresholdPx; } });
Object.defineProperty(exports, "selectedOutlineUvSnapThresholdPx", { enumerable: true, get: function () { return selected_outline_drag_2.selectedOutlineUvSnapThresholdPx; } });
Object.defineProperty(exports, "snapSelectedOutlineRotationDeltaDegrees", { enumerable: true, get: function () { return selected_outline_drag_2.snapSelectedOutlineRotationDeltaDegrees; } });
Object.defineProperty(exports, "snapSelectedOutlineTransformOriginUv", { enumerable: true, get: function () { return selected_outline_drag_2.snapSelectedOutlineTransformOriginUv; } });
Object.defineProperty(exports, "snapSelectedOutlineUv", { enumerable: true, get: function () { return selected_outline_drag_2.snapSelectedOutlineUv; } });
const selected_outline_measurement_2 = require("./selected-outline-measurement");
Object.defineProperty(exports, "getOutlineDoubleClickAction", { enumerable: true, get: function () { return selected_outline_measurement_2.getOutlineDoubleClickAction; } });
Object.defineProperty(exports, "getOutlineSelectionInteraction", { enumerable: true, get: function () { return selected_outline_measurement_2.getOutlineSelectionInteraction; } });
Object.defineProperty(exports, "getSelectedEffectFieldsBySequenceKey", { enumerable: true, get: function () { return selected_outline_measurement_2.getSelectedEffectFieldsBySequenceKey; } });
Object.defineProperty(exports, "getSelectedOutlineRotationCornerInfo", { enumerable: true, get: function () { return selected_outline_measurement_2.getSelectedOutlineRotationCornerInfo; } });
Object.defineProperty(exports, "getSelectedOutlineRotationDeltaDegrees", { enumerable: true, get: function () { return selected_outline_measurement_2.getSelectedOutlineRotationDeltaDegrees; } });
Object.defineProperty(exports, "getSelectedOutlineRotationPivot", { enumerable: true, get: function () { return selected_outline_measurement_2.getSelectedOutlineRotationPivot; } });
Object.defineProperty(exports, "getSelectedSequenceKeys", { enumerable: true, get: function () { return selected_outline_measurement_2.getSelectedSequenceKeys; } });
Object.defineProperty(exports, "getSequencesWithSelectableOutlines", { enumerable: true, get: function () { return selected_outline_measurement_2.getSequencesWithSelectableOutlines; } });
Object.defineProperty(exports, "getTransformedSvgViewportPoints", { enumerable: true, get: function () { return selected_outline_measurement_2.getTransformedSvgViewportPoints; } });
const selected_outline_types_2 = require("./selected-outline-types");
Object.defineProperty(exports, "selectedOutlineDragThresholdPx", { enumerable: true, get: function () { return selected_outline_types_2.selectedOutlineDragThresholdPx; } });
const outlineContainer = {
    position: 'absolute',
    inset: 0,
    pointerEvents: 'none',
    overflow: 'visible',
};
const SelectedOutlineSnapIndicators = ({ activeSnapPoints, compositionHeight, compositionWidth, scale }) => {
    if (activeSnapPoints.length === 0) {
        return null;
    }
    return (jsx_runtime_1.jsx("g", { pointerEvents: "none", children: activeSnapPoints.map((snapPoint) => {
            if (snapPoint.target.axis === 'x') {
                const x = snapPoint.target.position * scale;
                return (jsx_runtime_1.jsx("line", { x1: x, x2: x, y1: 0, y2: compositionHeight * scale, stroke: selected_outline_snap_1.selectedOutlineSnapIndicatorColor, strokeWidth: 1, vectorEffect: "non-scaling-stroke" }, `${snapPoint.target.axis}-${snapPoint.target.type}-${snapPoint.target.position}-${snapPoint.edge}`));
            }
            const y = snapPoint.target.position * scale;
            return (jsx_runtime_1.jsx("line", { x1: 0, x2: compositionWidth * scale, y1: y, y2: y, stroke: selected_outline_snap_1.selectedOutlineSnapIndicatorColor, strokeWidth: 1, vectorEffect: "non-scaling-stroke" }, `${snapPoint.target.axis}-${snapPoint.target.type}-${snapPoint.target.position}-${snapPoint.edge}`));
        }) }));
};
const outlinePointEqualityTolerance = 0.5;
const outlineAreaEqualityTolerance = 0.5;
const outlineBoundsOverlapTolerance = 0.5;
const outlinePointsAreEquivalent = (a, b) => {
    return (Math.abs(a.x - b.x) <= outlinePointEqualityTolerance &&
        Math.abs(a.y - b.y) <= outlinePointEqualityTolerance);
};
const outlinesHaveEquivalentHitArea = (a, b) => {
    if (a.points.length !== b.points.length) {
        return false;
    }
    for (let startIndex = 0; startIndex < b.points.length; startIndex++) {
        for (const direction of [1, -1]) {
            const pointsMatch = a.points.every((point, index) => {
                const bIndex = (startIndex + direction * index + b.points.length) % b.points.length;
                return outlinePointsAreEquivalent(point, b.points[bIndex]);
            });
            if (pointsMatch) {
                return true;
            }
        }
    }
    return false;
};
const getOutlineHitArea = (outline) => {
    let area = 0;
    for (let i = 0; i < outline.points.length; i++) {
        const current = outline.points[i];
        const next = outline.points[(i + 1) % outline.points.length];
        area += current.x * next.y - next.x * current.y;
    }
    return Math.abs(area) / 2;
};
const getOutlineBounds = (outline) => {
    const xs = outline.points.map((point) => point.x);
    const ys = outline.points.map((point) => point.y);
    return {
        maxX: Math.max(...xs),
        maxY: Math.max(...ys),
        minX: Math.min(...xs),
        minY: Math.min(...ys),
    };
};
const outlineBoundsOverlap = (a, b) => {
    const aBounds = getOutlineBounds(a);
    const bBounds = getOutlineBounds(b);
    return (aBounds.minX <= bBounds.maxX + outlineBoundsOverlapTolerance &&
        aBounds.maxX + outlineBoundsOverlapTolerance >= bBounds.minX &&
        aBounds.minY <= bBounds.maxY + outlineBoundsOverlapTolerance &&
        aBounds.maxY + outlineBoundsOverlapTolerance >= bBounds.minY);
};
const getSequenceId = (target) => {
    var _a;
    var _b;
    return (_b = (_a = target === null || target === void 0 ? void 0 : target.sequence) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
};
const getParentBySequenceId = ({ sequences, targetsByKey, }) => {
    const parentBySequenceId = new Map();
    for (const sequence of sequences) {
        parentBySequenceId.set(sequence.id, sequence.parent);
    }
    for (const target of targetsByKey.values()) {
        const sequenceId = getSequenceId(target);
        if (sequenceId !== null && !parentBySequenceId.has(sequenceId)) {
            parentBySequenceId.set(sequenceId, target.sequence.parent);
        }
    }
    return parentBySequenceId;
};
const isAncestorTarget = ({ ancestor, descendant, parentBySequenceId, }) => {
    var _a;
    var _b, _c;
    const ancestorId = getSequenceId(ancestor);
    if (ancestorId === null) {
        return false;
    }
    let parentId = (_b = (_a = descendant.sequence) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
    while (parentId !== null) {
        if (parentId === ancestorId) {
            return true;
        }
        parentId = (_c = parentBySequenceId.get(parentId)) !== null && _c !== void 0 ? _c : null;
    }
    return false;
};
const orderOutlineGroup = ({ outlines, parentBySequenceId, targetsByKey, }) => {
    var _a;
    var _b, _c, _d, _e;
    const incomingEdges = new Map();
    const outgoingEdges = new Map();
    const outlinesByKey = new Map(outlines.map((outline) => [outline.key, outline]));
    for (const outline of outlines) {
        incomingEdges.set(outline.key, new Set());
        outgoingEdges.set(outline.key, new Set());
    }
    const hasPath = ({ fromKey, seen, toKey, }) => {
        var _a;
        if (fromKey === toKey) {
            return true;
        }
        if (seen.has(fromKey)) {
            return false;
        }
        seen.add(fromKey);
        for (const nextKey of (_a = outgoingEdges.get(fromKey)) !== null && _a !== void 0 ? _a : []) {
            if (hasPath({ fromKey: nextKey, seen, toKey })) {
                return true;
            }
        }
        return false;
    };
    const addEdge = (before, after, options) => {
        if (before.key === after.key) {
            return;
        }
        const incoming = incomingEdges.get(after.key);
        const outgoing = outgoingEdges.get(before.key);
        if (incoming === undefined || outgoing === undefined) {
            throw new Error('Expected outline to be registered before adding edge');
        }
        if (outgoing.has(after.key)) {
            return;
        }
        if (hasPath({ fromKey: after.key, seen: new Set(), toKey: before.key })) {
            if (options === null || options === void 0 ? void 0 : options.skipIfCycle) {
                return;
            }
            throw new Error('Could not determine a stable outline rendering order');
        }
        incoming.add(before.key);
        outgoing.add(after.key);
    };
    const addAncestorConstraint = ({ ancestor, descendant, descendantContainsSelection, equivalentHitArea, }) => {
        // Usually, children should be above parents so nested elements are directly
        // selectable. If an unselected child has the same hit area as its parent, put
        // it below the parent so the wrapper can be selected. Once the child or
        // one of its properties is selected, keep it above the parent so it remains
        // directly draggable.
        if (equivalentHitArea && !descendantContainsSelection) {
            addEdge(descendant, ancestor);
        }
        else {
            addEdge(ancestor, descendant);
        }
    };
    const outlineBySequenceId = new Map();
    for (const outline of outlines) {
        const sequenceId = getSequenceId(targetsByKey.get(outline.key));
        if (sequenceId !== null) {
            outlineBySequenceId.set(sequenceId, outline);
        }
    }
    // Only constrain each outline against its nearest rendered ancestor. The
    // resulting graph follows the sequence tree, so pairwise subpixel equivalence
    // cannot introduce contradictory edges across three nested outlines.
    for (const descendant of outlines) {
        const descendantTarget = targetsByKey.get(descendant.key);
        let parentId = (_b = (_a = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.sequence) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
        while (parentId !== null) {
            const ancestor = outlineBySequenceId.get(parentId);
            if (ancestor !== undefined) {
                addAncestorConstraint({
                    ancestor,
                    descendant,
                    descendantContainsSelection: ((_c = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.selected) !== null && _c !== void 0 ? _c : false) ||
                        ((_d = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.containsSelection) !== null && _d !== void 0 ? _d : false),
                    equivalentHitArea: outlinesHaveEquivalentHitArea(ancestor, descendant),
                });
                break;
            }
            parentId = (_e = parentBySequenceId.get(parentId)) !== null && _e !== void 0 ? _e : null;
        }
    }
    // For unrelated overlapping outlines, put broader hit targets below
    // smaller ones so a large selected sequence cannot swallow clicks on
    // a more specific element in the same canvas area.
    for (let i = 0; i < outlines.length; i++) {
        for (let j = i + 1; j < outlines.length; j++) {
            const a = outlines[i];
            const b = outlines[j];
            const aTarget = targetsByKey.get(a.key);
            const bTarget = targetsByKey.get(b.key);
            if (aTarget === undefined || bTarget === undefined) {
                continue;
            }
            const aAncestorOfB = isAncestorTarget({
                ancestor: aTarget,
                descendant: bTarget,
                parentBySequenceId,
            });
            const bAncestorOfA = isAncestorTarget({
                ancestor: bTarget,
                descendant: aTarget,
                parentBySequenceId,
            });
            if (aAncestorOfB || bAncestorOfA || !outlineBoundsOverlap(a, b)) {
                continue;
            }
            const aArea = getOutlineHitArea(a);
            const bArea = getOutlineHitArea(b);
            if (Math.abs(aArea - bArea) <= outlineAreaEqualityTolerance) {
                continue;
            }
            if (aArea > bArea) {
                addEdge(a, b, { skipIfCycle: true });
            }
            else {
                addEdge(b, a, { skipIfCycle: true });
            }
        }
    }
    const emitted = new Set();
    const visiting = new Set();
    const ordered = [];
    const visit = (outline) => {
        var _a;
        if (emitted.has(outline.key)) {
            return;
        }
        if (visiting.has(outline.key)) {
            throw new Error('Could not determine a stable outline rendering order');
        }
        visiting.add(outline.key);
        for (const dependencyKey of (_a = incomingEdges.get(outline.key)) !== null && _a !== void 0 ? _a : []) {
            const dependency = outlinesByKey.get(dependencyKey);
            if (dependency === undefined) {
                throw new Error('Expected outline dependency to exist');
            }
            visit(dependency);
        }
        visiting.delete(outline.key);
        emitted.add(outline.key);
        ordered.push(outline);
    };
    for (const outline of outlines) {
        visit(outline);
    }
    return ordered;
};
const orderOutlinesForRendering = ({ outlines, sequences, targetsByKey, }) => {
    const parentBySequenceId = getParentBySequenceId({ sequences, targetsByKey });
    return orderOutlineGroup({
        outlines,
        parentBySequenceId,
        targetsByKey,
    });
};
exports.orderOutlinesForRendering = orderOutlinesForRendering;
const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, translationX, translationY, }) => {
    const { selectedItems, selectItem } = (0, TimelineSelection_1.useTimelineSelection)();
    const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
    const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
    const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
    const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
    const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
    const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
    const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
    const { getScaleLockState } = (0, react_1.useContext)(scale_lock_1.ScaleLockContext);
    const { editorShowOutlines } = (0, react_1.useContext)(editor_outlines_1.EditorShowOutlinesContext);
    const { editorShowGuides, guidesList } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
    const { frameBack, frameForward, getCurrentFrame, seek } = player_1.PlayerInternals.usePlayer();
    const keybindings = (0, use_keybinding_1.useKeybinding)();
    const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
    const [outlines, setOutlines] = (0, react_1.useState)([]);
    const [hoveredOutlineKey, setHoveredOutlineKey] = (0, react_1.useState)(null);
    const [draggingOutline, setDraggingOutline] = (0, react_1.useState)(false);
    const [activeSnapPoints, setActiveSnapPoints] = (0, react_1.useState)([]);
    const overlayRef = (0, react_1.useRef)(null);
    const keyboardNudgeSessionRef = (0, react_1.useRef)(null);
    const saveKeyboardNudgeSessionRef = (0, react_1.useRef)(() => undefined);
    const onDraggingChange = react_1.default.useCallback((dragging) => {
        setDraggingOutline(dragging);
        if (dragging) {
            setHoveredOutlineKey(null);
        }
        else {
            setActiveSnapPoints([]);
        }
    }, []);
    const onSnapPointsChange = (0, react_1.useCallback)((snapPoints) => {
        setActiveSnapPoints(snapPoints);
    }, []);
    const selectOutlineItem = (0, react_1.useCallback)((item, interaction) => {
        selectItem(item, interaction, undefined, { reveal: true });
    }, [selectItem]);
    const outlineTargets = (0, react_1.useMemo)(() => {
        if (!interactivity_enabled_1.studioInteractivityEnabled || !editorShowOutlines) {
            return [];
        }
        const selectedSequenceKeys = (0, selected_outline_measurement_1.getSelectedSequenceKeys)(selectedItems);
        const sequenceKeysContainingSelection = (0, selected_outline_measurement_1.getSequenceKeysContainingSelection)(selectedItems);
        const selectedEffectsBySequenceKey = (0, selected_outline_measurement_1.getSelectedEffectFieldsBySequenceKey)(selectedItems);
        const selectedTransformOriginInfo = (0, selected_outline_measurement_1.getSelectedTransformOriginInfo)(selectedItems);
        const clientId = previewServerState.type === 'connected'
            ? previewServerState.clientId
            : null;
        return (0, selected_outline_measurement_1.getSequencesWithSelectableOutlines)({
            sequences,
            overrideIdsToNodePaths: overrideIdToNodePathMappings,
        }).map(({ key, keyframeDisplayOffset, nodePathInfo, sequence }) => {
            var _a, _b, _c, _d, _e, _f;
            if (sequence.refForOutline === null) {
                throw new Error('Expected sequence to have a ref for outline');
            }
            const selected = selectedSequenceKeys.has(key);
            const containsSelection = sequenceKeysContainingSelection.has(key);
            const nodePath = nodePathInfo.sequenceSubscriptionKey;
            const { controls } = sequence;
            const nodePropStatuses = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath);
            const sourceFrame = timelinePosition - keyframeDisplayOffset;
            const dragOverrides = (_a = getDragOverrides(nodePath)) !== null && _a !== void 0 ? _a : {};
            const activeSchema = controls
                ? (0, selected_outline_drag_1.getSelectedOutlineActiveSchema)({
                    schema: controls.schema,
                    currentRuntimeValueDotNotation: controls.currentRuntimeValueDotNotation,
                    dragOverrides,
                    propStatus: nodePropStatuses,
                    frame: sourceFrame,
                })
                : null;
            const fieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.translateFieldKey];
            const propStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.translateFieldKey];
            const scaleFieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.scaleFieldKey];
            const scalePropStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.scaleFieldKey];
            const rotationFieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.rotateFieldKey];
            const rotationPropStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.rotateFieldKey];
            const transformOriginFieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.transformOriginFieldKey];
            const transformOriginPropStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.transformOriginFieldKey];
            const transformOriginValueForRotation = (transformOriginFieldSchema === null || transformOriginFieldSchema === void 0 ? void 0 : transformOriginFieldSchema.type) === 'transform-origin' &&
                ((transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'static' ||
                    (transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'keyframed')
                ? String((_b = remotion_1.Internals.getEffectiveVisualModeValue({
                    propStatus: transformOriginPropStatus,
                    dragOverrideValue: dragOverrides[selected_outline_types_1.transformOriginFieldKey],
                    defaultValue: transformOriginFieldSchema.default,
                    frame: sourceFrame,
                    shouldResortToDefaultValueIfUndefined: true,
                })) !== null && _b !== void 0 ? _b : transformOriginFieldSchema.default)
                : '50% 50%';
            const canDragStatus = (propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'static' ||
                ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'keyframed' &&
                    propStatus.interpolationFunction === 'interpolate');
            const canRotationDragStatus = (rotationPropStatus === null || rotationPropStatus === void 0 ? void 0 : rotationPropStatus.status) === 'static' ||
                ((rotationPropStatus === null || rotationPropStatus === void 0 ? void 0 : rotationPropStatus.status) === 'keyframed' &&
                    rotationPropStatus.interpolationFunction === 'interpolate');
            const canDrag = previewServerState.type === 'connected' &&
                controls !== null &&
                (fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.type) === 'translate' &&
                canDragStatus;
            const canScaleDragStatus = (scalePropStatus === null || scalePropStatus === void 0 ? void 0 : scalePropStatus.status) === 'static' ||
                ((scalePropStatus === null || scalePropStatus === void 0 ? void 0 : scalePropStatus.status) === 'keyframed' &&
                    scalePropStatus.interpolationFunction === 'interpolate');
            const canScaleDrag = previewServerState.type === 'connected' &&
                controls !== null &&
                (scaleFieldSchema === null || scaleFieldSchema === void 0 ? void 0 : scaleFieldSchema.type) === 'scale' &&
                canScaleDragStatus;
            const canRotationDrag = previewServerState.type === 'connected' &&
                controls !== null &&
                (rotationFieldSchema === null || rotationFieldSchema === void 0 ? void 0 : rotationFieldSchema.type) === 'rotation-css' &&
                canRotationDragStatus;
            const selectedForTransformOrigin = (selectedTransformOriginInfo === null || selectedTransformOriginInfo === void 0 ? void 0 : selectedTransformOriginInfo.sequenceKey) === key;
            const transformOriginSourceFrame = (selectedTransformOriginInfo === null || selectedTransformOriginInfo === void 0 ? void 0 : selectedTransformOriginInfo.displayFrame) === null ||
                (selectedTransformOriginInfo === null || selectedTransformOriginInfo === void 0 ? void 0 : selectedTransformOriginInfo.displayFrame) === undefined
                ? sourceFrame
                : selectedTransformOriginInfo.displayFrame - keyframeDisplayOffset;
            const canTransformOriginStatus = (transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'static' ||
                ((transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'keyframed' &&
                    transformOriginPropStatus.interpolationFunction === 'interpolate');
            const canTransformOriginTranslateStatus = (propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'static' ||
                ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'keyframed' &&
                    propStatus.interpolationFunction === 'interpolate');
            const canTransformOriginDrag = previewServerState.type === 'connected' &&
                selectedForTransformOrigin &&
                controls !== null &&
                (transformOriginFieldSchema === null || transformOriginFieldSchema === void 0 ? void 0 : transformOriginFieldSchema.type) === 'transform-origin' &&
                (fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.type) === 'translate' &&
                canTransformOriginStatus &&
                canTransformOriginTranslateStatus;
            const canDropEffect = previewServerState.type === 'connected' &&
                (controls === null || controls === void 0 ? void 0 : controls.supportsEffects) === true;
            return {
                key,
                containsSelection,
                effectDrop: canDropEffect
                    ? {
                        clientId: previewServerState.clientId,
                        fileName: nodePath.absolutePath,
                        nodePath,
                    }
                    : null,
                nodePathInfo,
                ref: sequence.refForOutline,
                selected,
                selection: { type: 'sequence', nodePathInfo },
                sequence,
                drag: canDrag
                    ? {
                        propStatus,
                        clientId: previewServerState.clientId,
                        fieldDefault: fieldSchema.default,
                        keyframeDisplayOffset,
                        nodePath,
                        schema: controls.schema,
                    }
                    : null,
                scaleDrag: canScaleDrag
                    ? {
                        propStatus: scalePropStatus,
                        clientId: previewServerState.clientId,
                        fieldDefault: scaleFieldSchema.default,
                        fieldSchema: scaleFieldSchema,
                        keyframeDisplayOffset,
                        linked: getScaleLockState({
                            nodePath,
                            fieldKey: selected_outline_types_1.scaleFieldKey,
                            defaultValue: (() => {
                                const dragOverrideValue = dragOverrides[selected_outline_types_1.scaleFieldKey];
                                const effectiveValue = remotion_1.Internals.getEffectiveVisualModeValue({
                                    propStatus: scalePropStatus,
                                    dragOverrideValue,
                                    defaultValue: scaleFieldSchema.default,
                                    shouldResortToDefaultValueIfUndefined: true,
                                });
                                const [x, y] = no_react_1.NoReactInternals.parseScaleValue(effectiveValue);
                                return x === y;
                            })(),
                        }),
                        nodePath,
                        schema: controls.schema,
                    }
                    : null,
                rotationDrag: canRotationDrag
                    ? {
                        propStatus: rotationPropStatus,
                        clientId: previewServerState.clientId,
                        fieldDefault: rotationFieldSchema.default,
                        fieldSchema: rotationFieldSchema,
                        keyframeDisplayOffset,
                        nodePath,
                        schema: controls.schema,
                        transformOriginValue: transformOriginValueForRotation,
                    }
                    : null,
                transformOriginDrag: canTransformOriginDrag
                    ? {
                        clientId: previewServerState.clientId,
                        keyframeDisplayOffset,
                        nodePath,
                        originDefault: transformOriginFieldSchema.default,
                        originPropStatus: transformOriginPropStatus,
                        originValue: String((_c = remotion_1.Internals.getEffectiveVisualModeValue({
                            propStatus: transformOriginPropStatus,
                            dragOverrideValue: dragOverrides[selected_outline_types_1.transformOriginFieldKey],
                            defaultValue: transformOriginFieldSchema.default,
                            frame: transformOriginSourceFrame,
                            shouldResortToDefaultValueIfUndefined: true,
                        })) !== null && _c !== void 0 ? _c : transformOriginFieldSchema.default),
                        rotateValue: String((rotationPropStatus === null || rotationPropStatus === void 0 ? void 0 : rotationPropStatus.status) === 'static' ||
                            (rotationPropStatus === null || rotationPropStatus === void 0 ? void 0 : rotationPropStatus.status) === 'keyframed'
                            ? ((_d = remotion_1.Internals.getEffectiveVisualModeValue({
                                propStatus: rotationPropStatus,
                                dragOverrideValue: dragOverrides[selected_outline_types_1.rotateFieldKey],
                                defaultValue: (rotationFieldSchema === null || rotationFieldSchema === void 0 ? void 0 : rotationFieldSchema.type) === 'rotation-css'
                                    ? rotationFieldSchema.default
                                    : '0deg',
                                frame: transformOriginSourceFrame,
                                shouldResortToDefaultValueIfUndefined: true,
                            })) !== null && _d !== void 0 ? _d : '0deg')
                            : '0deg'),
                        scaleValue: (scalePropStatus === null || scalePropStatus === void 0 ? void 0 : scalePropStatus.status) === 'static' ||
                            (scalePropStatus === null || scalePropStatus === void 0 ? void 0 : scalePropStatus.status) === 'keyframed'
                            ? String((_e = remotion_1.Internals.getEffectiveVisualModeValue({
                                propStatus: scalePropStatus,
                                dragOverrideValue: dragOverrides[selected_outline_types_1.scaleFieldKey],
                                defaultValue: (scaleFieldSchema === null || scaleFieldSchema === void 0 ? void 0 : scaleFieldSchema.type) === 'scale'
                                    ? scaleFieldSchema.default
                                    : 1,
                                frame: transformOriginSourceFrame,
                                shouldResortToDefaultValueIfUndefined: true,
                            })) !== null && _e !== void 0 ? _e : 1)
                            : '1',
                        schema: controls.schema,
                        sourceFrame: transformOriginSourceFrame,
                        translateDefault: fieldSchema.default,
                        translatePropStatus: propStatus,
                        translateValue: String((_f = remotion_1.Internals.getEffectiveVisualModeValue({
                            propStatus,
                            dragOverrideValue: dragOverrides[selected_outline_types_1.translateFieldKey],
                            defaultValue: fieldSchema.default,
                            frame: transformOriginSourceFrame,
                            shouldResortToDefaultValueIfUndefined: true,
                        })) !== null && _f !== void 0 ? _f : fieldSchema.default),
                    }
                    : null,
                uvHandles: containsSelection
                    ? (0, selected_outline_uv_1.getSelectedUvHandles)({
                        propStatuses,
                        clientId,
                        getEffectDragOverrides,
                        nodePath,
                        selectedEffects: selectedEffectsBySequenceKey.get(key),
                        sequence,
                        sourceFrame: timelinePosition - keyframeDisplayOffset,
                    })
                    : [],
            };
        });
    }, [
        propStatuses,
        getDragOverrides,
        getEffectDragOverrides,
        getScaleLockState,
        editorShowOutlines,
        overrideIdToNodePathMappings,
        previewServerState,
        selectedItems,
        sequences,
        timelinePosition,
    ]);
    (0, react_1.useEffect)(() => {
        if (hoveredOutlineKey !== null &&
            !outlineTargets.some((target) => target.key === hoveredOutlineKey)) {
            setHoveredOutlineKey(null);
        }
    }, [hoveredOutlineKey, outlineTargets]);
    const targetsByKey = (0, react_1.useMemo)(() => {
        return new Map(outlineTargets.map((target) => [target.key, target]));
    }, [outlineTargets]);
    const outlinesForRendering = (0, react_1.useMemo)(() => {
        return (0, exports.orderOutlinesForRendering)({ outlines, sequences, targetsByKey });
    }, [outlines, sequences, targetsByKey]);
    const outlinesByKey = (0, react_1.useMemo)(() => {
        return new Map(outlines.map((outline) => [outline.key, outline]));
    }, [outlines]);
    const allDragTargets = (0, react_1.useMemo)(() => {
        return outlineTargets.flatMap((target) => (target.selected || target.containsSelection) && target.drag !== null
            ? [target.drag]
            : []);
    }, [outlineTargets]);
    const allDragOutlines = (0, react_1.useMemo)(() => {
        return outlineTargets.flatMap((target) => {
            if ((!target.selected && !target.containsSelection) ||
                target.drag === null) {
                return [];
            }
            const outline = outlinesByKey.get(target.key);
            return outline === undefined ? [] : [outline];
        });
    }, [outlineTargets, outlinesByKey]);
    const allScaleDragTargets = (0, react_1.useMemo)(() => {
        return outlineTargets.flatMap((target) => target.selected && target.scaleDrag !== null ? [target.scaleDrag] : []);
    }, [outlineTargets]);
    const allRotationDragTargets = (0, react_1.useMemo)(() => {
        return outlineTargets.flatMap((target) => target.selected && target.rotationDrag !== null
            ? [target.rotationDrag]
            : []);
    }, [outlineTargets]);
    const guidesForSnap = (0, react_1.useMemo)(() => {
        if (!editorShowGuides || (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) !== 'composition') {
            return [];
        }
        return guidesList.filter((guide) => guide.compositionId === canvasContent.compositionId);
    }, [canvasContent, editorShowGuides, guidesList]);
    const snapTargets = (0, react_1.useMemo)(() => {
        return (0, selected_outline_snap_1.getSelectedOutlineSnapTargets)({
            compositionHeight,
            compositionWidth,
            guides: guidesForSnap,
        });
    }, [compositionHeight, compositionWidth, guidesForSnap]);
    const saveKeyboardNudgeSession = (0, react_1.useCallback)(() => {
        const session = keyboardNudgeSessionRef.current;
        if (session === null) {
            return;
        }
        keyboardNudgeSessionRef.current = null;
        const changes = (0, selected_outline_drag_1.getSelectedOutlineDragChanges)({
            dragStates: session.dragStates,
            lastValues: session.lastValues,
        });
        if (changes.length === 0) {
            (0, selected_outline_drag_1.clearSelectedOutlineDragOverrides)({
                clearDragOverrides,
                dragStates: session.dragStates,
            });
            return;
        }
        const staticChanges = changes.filter((change) => change.type === 'static');
        const keyframedChanges = changes.filter((change) => change.type === 'keyframed');
        Promise.all([
            staticChanges.length > 0
                ? (0, save_sequence_prop_1.saveSequenceProps)({
                    changes: staticChanges,
                    setPropStatuses,
                    clientId: session.clientId,
                    undoLabel: changes.length > 1 ? 'Move selected sequences' : 'Move sequence',
                    redoLabel: changes.length > 1
                        ? 'Move selected sequences back'
                        : 'Move sequence back',
                })
                : Promise.resolve(),
            ...keyframedChanges.map((change) => (0, call_add_keyframe_1.callAddSequenceKeyframe)({
                fileName: change.fileName,
                nodePath: change.nodePath,
                fieldKey: change.fieldKey,
                sourceFrame: change.sourceFrame,
                value: change.value,
                schema: change.schema,
                setPropStatuses,
                clientId: change.clientId,
            })),
        ])
            .catch((err) => {
            (0, NotificationCenter_1.showNotification)(`Could not save sequence props: ${err instanceof Error ? err.message : String(err)}`, 4000);
        })
            .finally(() => {
            (0, selected_outline_drag_1.clearSelectedOutlineDragOverrides)({
                clearDragOverrides,
                dragStates: session.dragStates,
            });
        });
    }, [clearDragOverrides, setPropStatuses]);
    (0, react_1.useEffect)(() => {
        saveKeyboardNudgeSessionRef.current = saveKeyboardNudgeSession;
    }, [saveKeyboardNudgeSession]);
    (0, react_1.useEffect)(() => {
        return () => {
            saveKeyboardNudgeSessionRef.current();
        };
    }, []);
    const seekWithArrowKey = (0, react_1.useCallback)((event, direction) => {
        if (direction === 'up' || direction === 'down') {
            return;
        }
        event.preventDefault();
        if (direction === 'left') {
            if (event.altKey) {
                seek(0);
                (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
                    direction: 'fit-left',
                    durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
                    frame: 0,
                });
            }
            else if (event.shiftKey) {
                frameBack((0, imperative_state_1.getCurrentFps)());
                (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
                    direction: 'fit-left',
                    durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
                    frame: Math.max(0, getCurrentFrame() - (0, imperative_state_1.getCurrentFps)()),
                });
            }
            else {
                frameBack(1);
                (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
                    direction: 'fit-left',
                    durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
                    frame: Math.max(0, getCurrentFrame() - 1),
                });
            }
            return;
        }
        if (event.altKey) {
            seek((0, imperative_state_1.getCurrentDuration)() - 1);
            (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
                direction: 'fit-right',
                durationInFrames: (0, imperative_state_1.getCurrentDuration)() - 1,
                frame: (0, imperative_state_1.getCurrentDuration)() - 1,
            });
        }
        else if (event.shiftKey) {
            frameForward((0, imperative_state_1.getCurrentFps)());
            (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
                direction: 'fit-right',
                durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
                frame: Math.min((0, imperative_state_1.getCurrentDuration)() - 1, getCurrentFrame() + (0, imperative_state_1.getCurrentFps)()),
            });
        }
        else {
            frameForward(1);
            (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
                direction: 'fit-right',
                durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
                frame: Math.min((0, imperative_state_1.getCurrentDuration)() - 1, getCurrentFrame() + 1),
            });
        }
    }, [frameBack, frameForward, getCurrentFrame, seek]);
    const onArrowKeyDown = (0, react_1.useCallback)((event) => {
        var _a;
        const direction = (0, selected_outline_drag_1.getSelectedOutlineKeyboardNudgeDirection)(event.key);
        if (direction === null) {
            return;
        }
        if (selectedItems.length === 0 || allDragTargets.length === 0) {
            seekWithArrowKey(event, direction);
            return;
        }
        if (event.altKey) {
            seekWithArrowKey(event, direction);
            return;
        }
        event.preventDefault();
        const activeSession = (_a = keyboardNudgeSessionRef.current) !== null && _a !== void 0 ? _a : (() => {
            const [firstDragTarget] = allDragTargets;
            if (firstDragTarget === undefined) {
                throw new Error('Expected a drag target');
            }
            return {
                clientId: firstDragTarget.clientId,
                deltaX: 0,
                deltaY: 0,
                dragStates: (0, selected_outline_drag_1.getSelectedOutlineDragStates)({
                    dragTargets: allDragTargets,
                    getDragOverrides,
                    timelinePosition,
                }),
                lastValues: new Map(),
            };
        })();
        keyboardNudgeSessionRef.current = activeSession;
        const nextDeltas = (0, selected_outline_drag_1.getSelectedOutlineKeyboardNudgeDeltas)({
            deltaX: activeSession.deltaX,
            deltaY: activeSession.deltaY,
            direction,
            shiftKey: event.shiftKey,
        });
        activeSession.deltaX = nextDeltas.deltaX;
        activeSession.deltaY = nextDeltas.deltaY;
        const lastValues = (0, selected_outline_drag_1.getSelectedOutlineDragValues)({
            dragStates: activeSession.dragStates,
            deltaX: activeSession.deltaX,
            deltaY: activeSession.deltaY,
        });
        activeSession.lastValues = lastValues;
        for (const dragState of activeSession.dragStates) {
            const value = lastValues.get(dragState.key);
            if (value === undefined) {
                throw new Error('Expected drag value to be available');
            }
            if (dragState.target.propStatus.status === 'keyframed') {
                setDragOverrides(dragState.target.nodePath, selected_outline_types_1.translateFieldKey, remotion_1.Internals.makeKeyframedDragOverride({
                    status: dragState.target.propStatus,
                    frame: dragState.sourceFrame,
                    value,
                }));
            }
            else {
                setDragOverrides(dragState.target.nodePath, selected_outline_types_1.translateFieldKey, remotion_1.Internals.makeStaticDragOverride(value));
            }
        }
    }, [
        allDragTargets,
        getDragOverrides,
        seekWithArrowKey,
        selectedItems.length,
        setDragOverrides,
        timelinePosition,
    ]);
    const onArrowKeyUp = (0, react_1.useCallback)((event) => {
        const direction = (0, selected_outline_drag_1.getSelectedOutlineKeyboardNudgeDirection)(event.key);
        if (direction === null || keyboardNudgeSessionRef.current === null) {
            return;
        }
        event.preventDefault();
        saveKeyboardNudgeSession();
    }, [saveKeyboardNudgeSession]);
    (0, react_1.useEffect)(() => {
        const keyDownBindings = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].map((key) => keybindings.registerKeybinding({
            event: 'keydown',
            key,
            callback: onArrowKeyDown,
            commandCtrlKey: false,
            preventDefault: false,
            triggerIfInputFieldFocused: false,
            keepRegisteredWhenNotHighestContext: false,
        }));
        const keyUpBindings = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].map((key) => keybindings.registerKeybinding({
            event: 'keyup',
            key,
            callback: onArrowKeyUp,
            commandCtrlKey: false,
            preventDefault: false,
            triggerIfInputFieldFocused: false,
            keepRegisteredWhenNotHighestContext: false,
        }));
        return () => {
            for (const binding of [...keyDownBindings, ...keyUpBindings]) {
                binding.unregister();
            }
        };
    }, [keybindings, onArrowKeyDown, onArrowKeyUp, saveKeyboardNudgeSession]);
    const updateOutlines = (0, react_1.useCallback)(() => {
        if (overlayRef.current === null || outlineTargets.length === 0) {
            setOutlines((prevOutlines) => prevOutlines.length === 0 ? prevOutlines : []);
            return;
        }
        const nextOutlines = (0, selected_outline_measurement_1.measureOutlines)(overlayRef.current, outlineTargets);
        setOutlines((prevOutlines) => (0, selected_outline_measurement_1.outlinesAreEqual)(prevOutlines, nextOutlines)
            ? prevOutlines
            : nextOutlines);
    }, [outlineTargets]);
    (0, react_1.useLayoutEffect)(() => {
        updateOutlines();
    }, [outlineTargets, scale, translationX, translationY, updateOutlines]);
    (0, react_1.useLayoutEffect)(() => {
        if (outlineTargets.length === 0 || typeof ResizeObserver === 'undefined') {
            return;
        }
        let animationFrame = null;
        const scheduleUpdate = () => {
            if (animationFrame !== null) {
                return;
            }
            animationFrame = requestAnimationFrame(() => {
                animationFrame = null;
                updateOutlines();
            });
        };
        const resizeObserver = new ResizeObserver(scheduleUpdate);
        if (overlayRef.current !== null) {
            resizeObserver.observe(overlayRef.current);
        }
        for (const target of outlineTargets) {
            if (target.ref.current !== null) {
                resizeObserver.observe(target.ref.current);
            }
        }
        return () => {
            if (animationFrame !== null) {
                cancelAnimationFrame(animationFrame);
            }
            resizeObserver.disconnect();
        };
    }, [outlineTargets, updateOutlines]);
    if (outlineTargets.length === 0) {
        return null;
    }
    return (jsx_runtime_1.jsxs("svg", { ref: overlayRef, style: outlineContainer, width: "100%", height: "100%", "aria-hidden": "true", children: [
            jsx_runtime_1.jsx(SelectedOutlineSnapIndicators, { activeSnapPoints: activeSnapPoints, compositionHeight: compositionHeight, compositionWidth: compositionWidth, scale: scale }), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineElement_1.SelectedOutlineElement, { allDragTargets: allDragTargets, allDragOutlines: allDragOutlines, allRotationDragTargets: allRotationDragTargets, allScaleDragTargets: allScaleDragTargets, dragging: draggingOutline, hovered: hoveredOutlineKey === outline.key, outline: outline, onDraggingChange: onDraggingChange, onHoverChange: setHoveredOutlineKey, onSnapPointsChange: onSnapPointsChange, onSelect: selectOutlineItem, scale: scale, snapTargets: snapTargets, target: targetsByKey.get(outline.key) }, outline.key))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineElement_1.SelectedOutlineTransformOriginHandle, { outline: outline, onDraggingChange: onDraggingChange, target: targetsByKey.get(outline.key) }, `${outline.key}-transform-origin`))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineUvControls_1.SelectedOutlineUvHandleConnectionLayer, { outline: outline, target: targetsByKey.get(outline.key) }, `${outline.key}-uv-connection-lines`))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineUvControls_1.SelectedOutlineUvHandleCircleLayer, { onDraggingChange: onDraggingChange, onSelect: selectOutlineItem, outline: outline, target: targetsByKey.get(outline.key) }, `${outline.key}-uv-handles`)))] }));
};
exports.SelectedOutlineOverlay = SelectedOutlineOverlay;
