import { __spreadArray, __read, __assign } from "../../../../../../../tslib@2.6.2/node_modules/tslib/tslib.es6.js";
import sync, { cancelSync, flushSync } from "../../../../../../../framesync@6.0.1/node_modules/framesync/dist/es/index.js";
import { animate } from "../../animation/animate.js";
import { SubscriptionManager } from "../../utils/subscription-manager.js";
import { mixValues } from "../animation/mix-values.js";
import { copyBoxInto } from "../geometry/copy.js";
import { translateAxis, transformBox, applyBoxDelta, applyTreeDeltas } from "../geometry/delta-apply.js";
import { calcRelativePosition, calcRelativeBox, calcBoxDelta, calcLength } from "../geometry/delta-calc.js";
import { removeBoxTransforms } from "../geometry/delta-remove.js";
import { createBox, createDelta } from "../geometry/models.js";
import { getValueTransition } from "../../animation/utils/transitions.js";
import { boxEquals, isDeltaZero } from "../geometry/utils.js";
import { NodeStack } from "../shared/stack.js";
import { scaleCorrectors } from "../styles/scale-correction.js";
import { buildProjectionTransform } from "../styles/transform.js";
import { eachAxis } from "../utils/each-axis.js";
import { hasTransform, hasScale } from "../utils/has-transform.js";
import { transformAxes } from "../../render/html/utils/transform.js";
import { FlatTree } from "../../render/utils/flat-tree.js";
import { resolveMotionValue } from "../../value/utils/resolve-motion-value.js";
import { globalProjectionState } from "./state.js";
import { mix } from "../../../../../../../popmotion@11.0.3/node_modules/popmotion/dist/es/utils/mix.js";
var animationTarget = 1e3;
function createProjectionNode(_a) {
  var attachResizeListener = _a.attachResizeListener, defaultParent = _a.defaultParent, measureScroll = _a.measureScroll, checkIsScrollRoot = _a.checkIsScrollRoot, resetTransform = _a.resetTransform;
  return (
    /** @class */
    function() {
      function ProjectionNode(id, latestValues, parent) {
        var _this = this;
        if (latestValues === void 0) {
          latestValues = {};
        }
        if (parent === void 0) {
          parent = defaultParent === null || defaultParent === void 0 ? void 0 : defaultParent();
        }
        this.children = /* @__PURE__ */ new Set();
        this.options = {};
        this.isTreeAnimating = false;
        this.isAnimationBlocked = false;
        this.isLayoutDirty = false;
        this.updateManuallyBlocked = false;
        this.updateBlockedByResize = false;
        this.isUpdating = false;
        this.isSVG = false;
        this.needsReset = false;
        this.shouldResetTransform = false;
        this.treeScale = { x: 1, y: 1 };
        this.eventHandlers = /* @__PURE__ */ new Map();
        this.potentialNodes = /* @__PURE__ */ new Map();
        this.checkUpdateFailed = function() {
          if (_this.isUpdating) {
            _this.isUpdating = false;
            _this.clearAllSnapshots();
          }
        };
        this.updateProjection = function() {
          _this.nodes.forEach(resolveTargetDelta);
          _this.nodes.forEach(calcProjection);
        };
        this.hasProjected = false;
        this.isVisible = true;
        this.animationProgress = 0;
        this.sharedNodes = /* @__PURE__ */ new Map();
        this.id = id;
        this.latestValues = latestValues;
        this.root = parent ? parent.root || parent : this;
        this.path = parent ? __spreadArray(__spreadArray([], __read(parent.path), false), [parent], false) : [];
        this.parent = parent;
        this.depth = parent ? parent.depth + 1 : 0;
        id && this.root.registerPotentialNode(id, this);
        for (var i = 0; i < this.path.length; i++) {
          this.path[i].shouldResetTransform = true;
        }
        if (this.root === this)
          this.nodes = new FlatTree();
      }
      ProjectionNode.prototype.addEventListener = function(name, handler) {
        if (!this.eventHandlers.has(name)) {
          this.eventHandlers.set(name, new SubscriptionManager());
        }
        return this.eventHandlers.get(name).add(handler);
      };
      ProjectionNode.prototype.notifyListeners = function(name) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
          args[_i - 1] = arguments[_i];
        }
        var subscriptionManager = this.eventHandlers.get(name);
        subscriptionManager === null || subscriptionManager === void 0 ? void 0 : subscriptionManager.notify.apply(subscriptionManager, __spreadArray([], __read(args), false));
      };
      ProjectionNode.prototype.hasListeners = function(name) {
        return this.eventHandlers.has(name);
      };
      ProjectionNode.prototype.registerPotentialNode = function(id, node) {
        this.potentialNodes.set(id, node);
      };
      ProjectionNode.prototype.mount = function(instance, isLayoutDirty) {
        var _this = this;
        var _a2;
        if (isLayoutDirty === void 0) {
          isLayoutDirty = false;
        }
        if (this.instance)
          return;
        this.isSVG = instance instanceof SVGElement && instance.tagName !== "svg";
        this.instance = instance;
        var _b = this.options, layoutId = _b.layoutId, layout = _b.layout, visualElement = _b.visualElement;
        if (visualElement && !visualElement.getInstance()) {
          visualElement.mount(instance);
        }
        this.root.nodes.add(this);
        (_a2 = this.parent) === null || _a2 === void 0 ? void 0 : _a2.children.add(this);
        this.id && this.root.potentialNodes.delete(this.id);
        if (isLayoutDirty && (layout || layoutId)) {
          this.isLayoutDirty = true;
        }
        if (attachResizeListener) {
          var unblockTimeout_1;
          var resizeUnblockUpdate_1 = function() {
            return _this.root.updateBlockedByResize = false;
          };
          attachResizeListener(instance, function() {
            _this.root.updateBlockedByResize = true;
            clearTimeout(unblockTimeout_1);
            unblockTimeout_1 = window.setTimeout(resizeUnblockUpdate_1, 250);
            if (globalProjectionState.hasAnimatedSinceResize) {
              globalProjectionState.hasAnimatedSinceResize = false;
              _this.nodes.forEach(finishAnimation);
            }
          });
        }
        if (layoutId) {
          this.root.registerSharedNode(layoutId, this);
        }
        if (this.options.animate !== false && visualElement && (layoutId || layout)) {
          this.addEventListener("didUpdate", function(_a3) {
            var _b2, _c, _d, _e, _f;
            var delta = _a3.delta, hasLayoutChanged = _a3.hasLayoutChanged, hasRelativeTargetChanged = _a3.hasRelativeTargetChanged, newLayout = _a3.layout;
            if (_this.isTreeAnimationBlocked()) {
              _this.target = void 0;
              _this.relativeTarget = void 0;
              return;
            }
            var layoutTransition = (_c = (_b2 = _this.options.transition) !== null && _b2 !== void 0 ? _b2 : visualElement.getDefaultTransition()) !== null && _c !== void 0 ? _c : defaultLayoutTransition;
            var _g = visualElement.getProps(), onLayoutAnimationStart = _g.onLayoutAnimationStart, onLayoutAnimationComplete = _g.onLayoutAnimationComplete;
            var targetChanged = !_this.targetLayout || !boxEquals(_this.targetLayout, newLayout) || hasRelativeTargetChanged;
            var hasOnlyRelativeTargetChanged = !hasLayoutChanged && hasRelativeTargetChanged;
            if (((_d = _this.resumeFrom) === null || _d === void 0 ? void 0 : _d.instance) || hasOnlyRelativeTargetChanged || hasLayoutChanged && (targetChanged || !_this.currentAnimation)) {
              if (_this.resumeFrom) {
                _this.resumingFrom = _this.resumeFrom;
                _this.resumingFrom.resumingFrom = void 0;
              }
              _this.setAnimationOrigin(delta, hasOnlyRelativeTargetChanged);
              var animationOptions = __assign(__assign({}, getValueTransition(layoutTransition, "layout")), { onPlay: onLayoutAnimationStart, onComplete: onLayoutAnimationComplete });
              if (visualElement.shouldReduceMotion) {
                animationOptions.delay = 0;
                animationOptions.type = false;
              }
              _this.startAnimation(animationOptions);
            } else {
              if (!hasLayoutChanged && _this.animationProgress === 0) {
                _this.finishAnimation();
              }
              _this.isLead() && ((_f = (_e = _this.options).onExitComplete) === null || _f === void 0 ? void 0 : _f.call(_e));
            }
            _this.targetLayout = newLayout;
          });
        }
      };
      ProjectionNode.prototype.unmount = function() {
        var _a2, _b;
        this.options.layoutId && this.willUpdate();
        this.root.nodes.remove(this);
        (_a2 = this.getStack()) === null || _a2 === void 0 ? void 0 : _a2.remove(this);
        (_b = this.parent) === null || _b === void 0 ? void 0 : _b.children.delete(this);
        this.instance = void 0;
        cancelSync.preRender(this.updateProjection);
      };
      ProjectionNode.prototype.blockUpdate = function() {
        this.updateManuallyBlocked = true;
      };
      ProjectionNode.prototype.unblockUpdate = function() {
        this.updateManuallyBlocked = false;
      };
      ProjectionNode.prototype.isUpdateBlocked = function() {
        return this.updateManuallyBlocked || this.updateBlockedByResize;
      };
      ProjectionNode.prototype.isTreeAnimationBlocked = function() {
        var _a2;
        return this.isAnimationBlocked || ((_a2 = this.parent) === null || _a2 === void 0 ? void 0 : _a2.isTreeAnimationBlocked()) || false;
      };
      ProjectionNode.prototype.startUpdate = function() {
        var _a2;
        if (this.isUpdateBlocked())
          return;
        this.isUpdating = true;
        (_a2 = this.nodes) === null || _a2 === void 0 ? void 0 : _a2.forEach(resetRotation);
      };
      ProjectionNode.prototype.willUpdate = function(shouldNotifyListeners) {
        var _a2, _b, _c;
        if (shouldNotifyListeners === void 0) {
          shouldNotifyListeners = true;
        }
        if (this.root.isUpdateBlocked()) {
          (_b = (_a2 = this.options).onExitComplete) === null || _b === void 0 ? void 0 : _b.call(_a2);
          return;
        }
        !this.root.isUpdating && this.root.startUpdate();
        if (this.isLayoutDirty)
          return;
        this.isLayoutDirty = true;
        for (var i = 0; i < this.path.length; i++) {
          var node = this.path[i];
          node.shouldResetTransform = true;
          node.updateScroll();
        }
        var _d = this.options, layoutId = _d.layoutId, layout = _d.layout;
        if (layoutId === void 0 && !layout)
          return;
        var transformTemplate = (_c = this.options.visualElement) === null || _c === void 0 ? void 0 : _c.getProps().transformTemplate;
        this.prevTransformTemplateValue = transformTemplate === null || transformTemplate === void 0 ? void 0 : transformTemplate(this.latestValues, "");
        this.updateSnapshot();
        shouldNotifyListeners && this.notifyListeners("willUpdate");
      };
      ProjectionNode.prototype.didUpdate = function() {
        var updateWasBlocked = this.isUpdateBlocked();
        if (updateWasBlocked) {
          this.unblockUpdate();
          this.clearAllSnapshots();
          this.nodes.forEach(clearMeasurements);
          return;
        }
        if (!this.isUpdating)
          return;
        this.isUpdating = false;
        if (this.potentialNodes.size) {
          this.potentialNodes.forEach(mountNodeEarly);
          this.potentialNodes.clear();
        }
        this.nodes.forEach(resetTransformStyle);
        this.nodes.forEach(updateLayout);
        this.nodes.forEach(notifyLayoutUpdate);
        this.clearAllSnapshots();
        flushSync.update();
        flushSync.preRender();
        flushSync.render();
      };
      ProjectionNode.prototype.clearAllSnapshots = function() {
        this.nodes.forEach(clearSnapshot);
        this.sharedNodes.forEach(removeLeadSnapshots);
      };
      ProjectionNode.prototype.scheduleUpdateProjection = function() {
        sync.preRender(this.updateProjection, false, true);
      };
      ProjectionNode.prototype.scheduleCheckAfterUnmount = function() {
        var _this = this;
        sync.postRender(function() {
          if (_this.isLayoutDirty) {
            _this.root.didUpdate();
          } else {
            _this.root.checkUpdateFailed();
          }
        });
      };
      ProjectionNode.prototype.updateSnapshot = function() {
        if (this.snapshot || !this.instance)
          return;
        var measured = this.measure();
        var layout = this.removeTransform(this.removeElementScroll(measured));
        roundBox(layout);
        this.snapshot = {
          measured,
          layout,
          latestValues: {}
        };
      };
      ProjectionNode.prototype.updateLayout = function() {
        var _a2;
        if (!this.instance)
          return;
        this.updateScroll();
        if (!(this.options.alwaysMeasureLayout && this.isLead()) && !this.isLayoutDirty) {
          return;
        }
        if (this.resumeFrom && !this.resumeFrom.instance) {
          for (var i = 0; i < this.path.length; i++) {
            var node = this.path[i];
            node.updateScroll();
          }
        }
        var measured = this.measure();
        roundBox(measured);
        var prevLayout = this.layout;
        this.layout = {
          measured,
          actual: this.removeElementScroll(measured)
        };
        this.layoutCorrected = createBox();
        this.isLayoutDirty = false;
        this.projectionDelta = void 0;
        this.notifyListeners("measure", this.layout.actual);
        (_a2 = this.options.visualElement) === null || _a2 === void 0 ? void 0 : _a2.notifyLayoutMeasure(this.layout.actual, prevLayout === null || prevLayout === void 0 ? void 0 : prevLayout.actual);
      };
      ProjectionNode.prototype.updateScroll = function() {
        if (this.options.layoutScroll && this.instance) {
          this.isScrollRoot = checkIsScrollRoot(this.instance);
          this.scroll = measureScroll(this.instance);
        }
      };
      ProjectionNode.prototype.resetTransform = function() {
        var _a2;
        if (!resetTransform)
          return;
        var isResetRequested = this.isLayoutDirty || this.shouldResetTransform;
        var hasProjection = this.projectionDelta && !isDeltaZero(this.projectionDelta);
        var transformTemplate = (_a2 = this.options.visualElement) === null || _a2 === void 0 ? void 0 : _a2.getProps().transformTemplate;
        var transformTemplateValue = transformTemplate === null || transformTemplate === void 0 ? void 0 : transformTemplate(this.latestValues, "");
        var transformTemplateHasChanged = transformTemplateValue !== this.prevTransformTemplateValue;
        if (isResetRequested && (hasProjection || hasTransform(this.latestValues) || transformTemplateHasChanged)) {
          resetTransform(this.instance, transformTemplateValue);
          this.shouldResetTransform = false;
          this.scheduleRender();
        }
      };
      ProjectionNode.prototype.measure = function() {
        var visualElement = this.options.visualElement;
        if (!visualElement)
          return createBox();
        var box = visualElement.measureViewportBox();
        var scroll = this.root.scroll;
        if (scroll) {
          translateAxis(box.x, scroll.x);
          translateAxis(box.y, scroll.y);
        }
        return box;
      };
      ProjectionNode.prototype.removeElementScroll = function(box) {
        var boxWithoutScroll = createBox();
        copyBoxInto(boxWithoutScroll, box);
        for (var i = 0; i < this.path.length; i++) {
          var node = this.path[i];
          var scroll_1 = node.scroll, options = node.options, isScrollRoot = node.isScrollRoot;
          if (node !== this.root && scroll_1 && options.layoutScroll) {
            if (isScrollRoot) {
              copyBoxInto(boxWithoutScroll, box);
              var rootScroll = this.root.scroll;
              if (rootScroll) {
                translateAxis(boxWithoutScroll.x, -rootScroll.x);
                translateAxis(boxWithoutScroll.y, -rootScroll.y);
              }
            }
            translateAxis(boxWithoutScroll.x, scroll_1.x);
            translateAxis(boxWithoutScroll.y, scroll_1.y);
          }
        }
        return boxWithoutScroll;
      };
      ProjectionNode.prototype.applyTransform = function(box, transformOnly) {
        if (transformOnly === void 0) {
          transformOnly = false;
        }
        var withTransforms = createBox();
        copyBoxInto(withTransforms, box);
        for (var i = 0; i < this.path.length; i++) {
          var node = this.path[i];
          if (!transformOnly && node.options.layoutScroll && node.scroll && node !== node.root) {
            transformBox(withTransforms, {
              x: -node.scroll.x,
              y: -node.scroll.y
            });
          }
          if (!hasTransform(node.latestValues))
            continue;
          transformBox(withTransforms, node.latestValues);
        }
        if (hasTransform(this.latestValues)) {
          transformBox(withTransforms, this.latestValues);
        }
        return withTransforms;
      };
      ProjectionNode.prototype.removeTransform = function(box) {
        var _a2;
        var boxWithoutTransform = createBox();
        copyBoxInto(boxWithoutTransform, box);
        for (var i = 0; i < this.path.length; i++) {
          var node = this.path[i];
          if (!node.instance)
            continue;
          if (!hasTransform(node.latestValues))
            continue;
          hasScale(node.latestValues) && node.updateSnapshot();
          var sourceBox = createBox();
          var nodeBox = node.measure();
          copyBoxInto(sourceBox, nodeBox);
          removeBoxTransforms(boxWithoutTransform, node.latestValues, (_a2 = node.snapshot) === null || _a2 === void 0 ? void 0 : _a2.layout, sourceBox);
        }
        if (hasTransform(this.latestValues)) {
          removeBoxTransforms(boxWithoutTransform, this.latestValues);
        }
        return boxWithoutTransform;
      };
      ProjectionNode.prototype.setTargetDelta = function(delta) {
        this.targetDelta = delta;
        this.root.scheduleUpdateProjection();
      };
      ProjectionNode.prototype.setOptions = function(options) {
        var _a2;
        this.options = __assign(__assign(__assign({}, this.options), options), { crossfade: (_a2 = options.crossfade) !== null && _a2 !== void 0 ? _a2 : true });
      };
      ProjectionNode.prototype.clearMeasurements = function() {
        this.scroll = void 0;
        this.layout = void 0;
        this.snapshot = void 0;
        this.prevTransformTemplateValue = void 0;
        this.targetDelta = void 0;
        this.target = void 0;
        this.isLayoutDirty = false;
      };
      ProjectionNode.prototype.resolveTargetDelta = function() {
        var _a2;
        var _b = this.options, layout = _b.layout, layoutId = _b.layoutId;
        if (!this.layout || !(layout || layoutId))
          return;
        if (!this.targetDelta && !this.relativeTarget) {
          this.relativeParent = this.getClosestProjectingParent();
          if (this.relativeParent && this.relativeParent.layout) {
            this.relativeTarget = createBox();
            this.relativeTargetOrigin = createBox();
            calcRelativePosition(this.relativeTargetOrigin, this.layout.actual, this.relativeParent.layout.actual);
            copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
          }
        }
        if (!this.relativeTarget && !this.targetDelta)
          return;
        if (!this.target) {
          this.target = createBox();
          this.targetWithTransforms = createBox();
        }
        if (this.relativeTarget && this.relativeTargetOrigin && ((_a2 = this.relativeParent) === null || _a2 === void 0 ? void 0 : _a2.target)) {
          calcRelativeBox(this.target, this.relativeTarget, this.relativeParent.target);
        } else if (this.targetDelta) {
          if (Boolean(this.resumingFrom)) {
            this.target = this.applyTransform(this.layout.actual);
          } else {
            copyBoxInto(this.target, this.layout.actual);
          }
          applyBoxDelta(this.target, this.targetDelta);
        } else {
          copyBoxInto(this.target, this.layout.actual);
        }
        if (this.attemptToResolveRelativeTarget) {
          this.attemptToResolveRelativeTarget = false;
          this.relativeParent = this.getClosestProjectingParent();
          if (this.relativeParent && Boolean(this.relativeParent.resumingFrom) === Boolean(this.resumingFrom) && !this.relativeParent.options.layoutScroll && this.relativeParent.target) {
            this.relativeTarget = createBox();
            this.relativeTargetOrigin = createBox();
            calcRelativePosition(this.relativeTargetOrigin, this.target, this.relativeParent.target);
            copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
          }
        }
      };
      ProjectionNode.prototype.getClosestProjectingParent = function() {
        if (!this.parent || hasTransform(this.parent.latestValues))
          return void 0;
        if ((this.parent.relativeTarget || this.parent.targetDelta) && this.parent.layout) {
          return this.parent;
        } else {
          return this.parent.getClosestProjectingParent();
        }
      };
      ProjectionNode.prototype.calcProjection = function() {
        var _a2;
        var _b = this.options, layout = _b.layout, layoutId = _b.layoutId;
        this.isTreeAnimating = Boolean(((_a2 = this.parent) === null || _a2 === void 0 ? void 0 : _a2.isTreeAnimating) || this.currentAnimation || this.pendingAnimation);
        if (!this.isTreeAnimating) {
          this.targetDelta = this.relativeTarget = void 0;
        }
        if (!this.layout || !(layout || layoutId))
          return;
        var lead = this.getLead();
        copyBoxInto(this.layoutCorrected, this.layout.actual);
        applyTreeDeltas(this.layoutCorrected, this.treeScale, this.path, Boolean(this.resumingFrom) || this !== lead);
        var target = lead.target;
        if (!target)
          return;
        if (!this.projectionDelta) {
          this.projectionDelta = createDelta();
          this.projectionDeltaWithTransform = createDelta();
        }
        var prevTreeScaleX = this.treeScale.x;
        var prevTreeScaleY = this.treeScale.y;
        var prevProjectionTransform = this.projectionTransform;
        calcBoxDelta(this.projectionDelta, this.layoutCorrected, target, this.latestValues);
        this.projectionTransform = buildProjectionTransform(this.projectionDelta, this.treeScale);
        if (this.projectionTransform !== prevProjectionTransform || this.treeScale.x !== prevTreeScaleX || this.treeScale.y !== prevTreeScaleY) {
          this.hasProjected = true;
          this.scheduleRender();
          this.notifyListeners("projectionUpdate", target);
        }
      };
      ProjectionNode.prototype.hide = function() {
        this.isVisible = false;
      };
      ProjectionNode.prototype.show = function() {
        this.isVisible = true;
      };
      ProjectionNode.prototype.scheduleRender = function(notifyAll) {
        var _a2, _b, _c;
        if (notifyAll === void 0) {
          notifyAll = true;
        }
        (_b = (_a2 = this.options).scheduleRender) === null || _b === void 0 ? void 0 : _b.call(_a2);
        notifyAll && ((_c = this.getStack()) === null || _c === void 0 ? void 0 : _c.scheduleRender());
        if (this.resumingFrom && !this.resumingFrom.instance) {
          this.resumingFrom = void 0;
        }
      };
      ProjectionNode.prototype.setAnimationOrigin = function(delta, hasOnlyRelativeTargetChanged) {
        var _this = this;
        var _a2;
        if (hasOnlyRelativeTargetChanged === void 0) {
          hasOnlyRelativeTargetChanged = false;
        }
        var snapshot = this.snapshot;
        var snapshotLatestValues = (snapshot === null || snapshot === void 0 ? void 0 : snapshot.latestValues) || {};
        var mixedValues = __assign({}, this.latestValues);
        var targetDelta = createDelta();
        this.relativeTarget = this.relativeTargetOrigin = void 0;
        this.attemptToResolveRelativeTarget = !hasOnlyRelativeTargetChanged;
        var relativeLayout = createBox();
        var isSharedLayoutAnimation = snapshot === null || snapshot === void 0 ? void 0 : snapshot.isShared;
        var isOnlyMember = (((_a2 = this.getStack()) === null || _a2 === void 0 ? void 0 : _a2.members.length) || 0) <= 1;
        var shouldCrossfadeOpacity = Boolean(isSharedLayoutAnimation && !isOnlyMember && this.options.crossfade === true && !this.path.some(hasOpacityCrossfade));
        this.animationProgress = 0;
        this.mixTargetDelta = function(latest) {
          var _a3;
          var progress = latest / 1e3;
          mixAxisDelta(targetDelta.x, delta.x, progress);
          mixAxisDelta(targetDelta.y, delta.y, progress);
          _this.setTargetDelta(targetDelta);
          if (_this.relativeTarget && _this.relativeTargetOrigin && _this.layout && ((_a3 = _this.relativeParent) === null || _a3 === void 0 ? void 0 : _a3.layout)) {
            calcRelativePosition(relativeLayout, _this.layout.actual, _this.relativeParent.layout.actual);
            mixBox(_this.relativeTarget, _this.relativeTargetOrigin, relativeLayout, progress);
          }
          if (isSharedLayoutAnimation) {
            _this.animationValues = mixedValues;
            mixValues(mixedValues, snapshotLatestValues, _this.latestValues, progress, shouldCrossfadeOpacity, isOnlyMember);
          }
          _this.root.scheduleUpdateProjection();
          _this.scheduleRender();
          _this.animationProgress = progress;
        };
        this.mixTargetDelta(0);
      };
      ProjectionNode.prototype.startAnimation = function(options) {
        var _this = this;
        var _a2, _b;
        this.notifyListeners("animationStart");
        (_a2 = this.currentAnimation) === null || _a2 === void 0 ? void 0 : _a2.stop();
        if (this.resumingFrom) {
          (_b = this.resumingFrom.currentAnimation) === null || _b === void 0 ? void 0 : _b.stop();
        }
        if (this.pendingAnimation) {
          cancelSync.update(this.pendingAnimation);
          this.pendingAnimation = void 0;
        }
        this.pendingAnimation = sync.update(function() {
          globalProjectionState.hasAnimatedSinceResize = true;
          _this.currentAnimation = animate(0, animationTarget, __assign(__assign({}, options), { onUpdate: function(latest) {
            var _a3;
            _this.mixTargetDelta(latest);
            (_a3 = options.onUpdate) === null || _a3 === void 0 ? void 0 : _a3.call(options, latest);
          }, onComplete: function() {
            var _a3;
            (_a3 = options.onComplete) === null || _a3 === void 0 ? void 0 : _a3.call(options);
            _this.completeAnimation();
          } }));
          if (_this.resumingFrom) {
            _this.resumingFrom.currentAnimation = _this.currentAnimation;
          }
          _this.pendingAnimation = void 0;
        });
      };
      ProjectionNode.prototype.completeAnimation = function() {
        var _a2;
        if (this.resumingFrom) {
          this.resumingFrom.currentAnimation = void 0;
          this.resumingFrom.preserveOpacity = void 0;
        }
        (_a2 = this.getStack()) === null || _a2 === void 0 ? void 0 : _a2.exitAnimationComplete();
        this.resumingFrom = this.currentAnimation = this.animationValues = void 0;
        this.notifyListeners("animationComplete");
      };
      ProjectionNode.prototype.finishAnimation = function() {
        var _a2;
        if (this.currentAnimation) {
          (_a2 = this.mixTargetDelta) === null || _a2 === void 0 ? void 0 : _a2.call(this, animationTarget);
          this.currentAnimation.stop();
        }
        this.completeAnimation();
      };
      ProjectionNode.prototype.applyTransformsToTarget = function() {
        var _a2 = this.getLead(), targetWithTransforms = _a2.targetWithTransforms, target = _a2.target, layout = _a2.layout, latestValues = _a2.latestValues;
        if (!targetWithTransforms || !target || !layout)
          return;
        copyBoxInto(targetWithTransforms, target);
        transformBox(targetWithTransforms, latestValues);
        calcBoxDelta(this.projectionDeltaWithTransform, this.layoutCorrected, targetWithTransforms, latestValues);
      };
      ProjectionNode.prototype.registerSharedNode = function(layoutId, node) {
        var _a2, _b, _c;
        if (!this.sharedNodes.has(layoutId)) {
          this.sharedNodes.set(layoutId, new NodeStack());
        }
        var stack = this.sharedNodes.get(layoutId);
        stack.add(node);
        node.promote({
          transition: (_a2 = node.options.initialPromotionConfig) === null || _a2 === void 0 ? void 0 : _a2.transition,
          preserveFollowOpacity: (_c = (_b = node.options.initialPromotionConfig) === null || _b === void 0 ? void 0 : _b.shouldPreserveFollowOpacity) === null || _c === void 0 ? void 0 : _c.call(_b, node)
        });
      };
      ProjectionNode.prototype.isLead = function() {
        var stack = this.getStack();
        return stack ? stack.lead === this : true;
      };
      ProjectionNode.prototype.getLead = function() {
        var _a2;
        var layoutId = this.options.layoutId;
        return layoutId ? ((_a2 = this.getStack()) === null || _a2 === void 0 ? void 0 : _a2.lead) || this : this;
      };
      ProjectionNode.prototype.getPrevLead = function() {
        var _a2;
        var layoutId = this.options.layoutId;
        return layoutId ? (_a2 = this.getStack()) === null || _a2 === void 0 ? void 0 : _a2.prevLead : void 0;
      };
      ProjectionNode.prototype.getStack = function() {
        var layoutId = this.options.layoutId;
        if (layoutId)
          return this.root.sharedNodes.get(layoutId);
      };
      ProjectionNode.prototype.promote = function(_a2) {
        var _b = _a2 === void 0 ? {} : _a2, needsReset = _b.needsReset, transition = _b.transition, preserveFollowOpacity = _b.preserveFollowOpacity;
        var stack = this.getStack();
        if (stack)
          stack.promote(this, preserveFollowOpacity);
        if (needsReset) {
          this.projectionDelta = void 0;
          this.needsReset = true;
        }
        if (transition)
          this.setOptions({ transition });
      };
      ProjectionNode.prototype.relegate = function() {
        var stack = this.getStack();
        if (stack) {
          return stack.relegate(this);
        } else {
          return false;
        }
      };
      ProjectionNode.prototype.resetRotation = function() {
        var visualElement = this.options.visualElement;
        if (!visualElement)
          return;
        var hasRotate = false;
        var resetValues = {};
        for (var i = 0; i < transformAxes.length; i++) {
          var axis = transformAxes[i];
          var key = "rotate" + axis;
          if (!visualElement.getStaticValue(key)) {
            continue;
          }
          hasRotate = true;
          resetValues[key] = visualElement.getStaticValue(key);
          visualElement.setStaticValue(key, 0);
        }
        if (!hasRotate)
          return;
        visualElement === null || visualElement === void 0 ? void 0 : visualElement.syncRender();
        for (var key in resetValues) {
          visualElement.setStaticValue(key, resetValues[key]);
        }
        visualElement.scheduleRender();
      };
      ProjectionNode.prototype.getProjectionStyles = function(styleProp) {
        var _a2, _b, _c, _d, _e, _f;
        if (styleProp === void 0) {
          styleProp = {};
        }
        var styles = {};
        if (!this.instance || this.isSVG)
          return styles;
        if (!this.isVisible) {
          return { visibility: "hidden" };
        } else {
          styles.visibility = "";
        }
        var transformTemplate = (_a2 = this.options.visualElement) === null || _a2 === void 0 ? void 0 : _a2.getProps().transformTemplate;
        if (this.needsReset) {
          this.needsReset = false;
          styles.opacity = "";
          styles.pointerEvents = resolveMotionValue(styleProp.pointerEvents) || "";
          styles.transform = transformTemplate ? transformTemplate(this.latestValues, "") : "none";
          return styles;
        }
        var lead = this.getLead();
        if (!this.projectionDelta || !this.layout || !lead.target) {
          var emptyStyles = {};
          if (this.options.layoutId) {
            emptyStyles.opacity = (_b = this.latestValues.opacity) !== null && _b !== void 0 ? _b : 1;
            emptyStyles.pointerEvents = resolveMotionValue(styleProp.pointerEvents) || "";
          }
          if (this.hasProjected && !hasTransform(this.latestValues)) {
            emptyStyles.transform = transformTemplate ? transformTemplate({}, "") : "none";
            this.hasProjected = false;
          }
          return emptyStyles;
        }
        var valuesToRender = lead.animationValues || lead.latestValues;
        this.applyTransformsToTarget();
        styles.transform = buildProjectionTransform(this.projectionDeltaWithTransform, this.treeScale, valuesToRender);
        if (transformTemplate) {
          styles.transform = transformTemplate(valuesToRender, styles.transform);
        }
        var _g = this.projectionDelta, x = _g.x, y = _g.y;
        styles.transformOrigin = "".concat(x.origin * 100, "% ").concat(y.origin * 100, "% 0");
        if (lead.animationValues) {
          styles.opacity = lead === this ? (_d = (_c = valuesToRender.opacity) !== null && _c !== void 0 ? _c : this.latestValues.opacity) !== null && _d !== void 0 ? _d : 1 : this.preserveOpacity ? this.latestValues.opacity : valuesToRender.opacityExit;
        } else {
          styles.opacity = lead === this ? (_e = valuesToRender.opacity) !== null && _e !== void 0 ? _e : "" : (_f = valuesToRender.opacityExit) !== null && _f !== void 0 ? _f : 0;
        }
        for (var key in scaleCorrectors) {
          if (valuesToRender[key] === void 0)
            continue;
          var _h = scaleCorrectors[key], correct = _h.correct, applyTo = _h.applyTo;
          var corrected = correct(valuesToRender[key], lead);
          if (applyTo) {
            var num = applyTo.length;
            for (var i = 0; i < num; i++) {
              styles[applyTo[i]] = corrected;
            }
          } else {
            styles[key] = corrected;
          }
        }
        if (this.options.layoutId) {
          styles.pointerEvents = lead === this ? resolveMotionValue(styleProp.pointerEvents) || "" : "none";
        }
        return styles;
      };
      ProjectionNode.prototype.clearSnapshot = function() {
        this.resumeFrom = this.snapshot = void 0;
      };
      ProjectionNode.prototype.resetTree = function() {
        this.root.nodes.forEach(function(node) {
          var _a2;
          return (_a2 = node.currentAnimation) === null || _a2 === void 0 ? void 0 : _a2.stop();
        });
        this.root.nodes.forEach(clearMeasurements);
        this.root.sharedNodes.clear();
      };
      return ProjectionNode;
    }()
  );
}
function updateLayout(node) {
  node.updateLayout();
}
function notifyLayoutUpdate(node) {
  var _a, _b, _c, _d;
  var snapshot = (_b = (_a = node.resumeFrom) === null || _a === void 0 ? void 0 : _a.snapshot) !== null && _b !== void 0 ? _b : node.snapshot;
  if (node.isLead() && node.layout && snapshot && node.hasListeners("didUpdate")) {
    var _e = node.layout, layout_1 = _e.actual, measuredLayout = _e.measured;
    if (node.options.animationType === "size") {
      eachAxis(function(axis) {
        var axisSnapshot = snapshot.isShared ? snapshot.measured[axis] : snapshot.layout[axis];
        var length = calcLength(axisSnapshot);
        axisSnapshot.min = layout_1[axis].min;
        axisSnapshot.max = axisSnapshot.min + length;
      });
    } else if (node.options.animationType === "position") {
      eachAxis(function(axis) {
        var axisSnapshot = snapshot.isShared ? snapshot.measured[axis] : snapshot.layout[axis];
        var length = calcLength(layout_1[axis]);
        axisSnapshot.max = axisSnapshot.min + length;
      });
    }
    var layoutDelta = createDelta();
    calcBoxDelta(layoutDelta, layout_1, snapshot.layout);
    var visualDelta = createDelta();
    if (snapshot.isShared) {
      calcBoxDelta(visualDelta, node.applyTransform(measuredLayout, true), snapshot.measured);
    } else {
      calcBoxDelta(visualDelta, layout_1, snapshot.layout);
    }
    var hasLayoutChanged = !isDeltaZero(layoutDelta);
    var hasRelativeTargetChanged = false;
    if (!node.resumeFrom) {
      node.relativeParent = node.getClosestProjectingParent();
      if (node.relativeParent && !node.relativeParent.resumeFrom) {
        var _f = node.relativeParent, parentSnapshot = _f.snapshot, parentLayout = _f.layout;
        if (parentSnapshot && parentLayout) {
          var relativeSnapshot = createBox();
          calcRelativePosition(relativeSnapshot, snapshot.layout, parentSnapshot.layout);
          var relativeLayout = createBox();
          calcRelativePosition(relativeLayout, layout_1, parentLayout.actual);
          if (!boxEquals(relativeSnapshot, relativeLayout)) {
            hasRelativeTargetChanged = true;
          }
        }
      }
    }
    node.notifyListeners("didUpdate", {
      layout: layout_1,
      snapshot,
      delta: visualDelta,
      layoutDelta,
      hasLayoutChanged,
      hasRelativeTargetChanged
    });
  } else if (node.isLead()) {
    (_d = (_c = node.options).onExitComplete) === null || _d === void 0 ? void 0 : _d.call(_c);
  }
  node.options.transition = void 0;
}
function clearSnapshot(node) {
  node.clearSnapshot();
}
function clearMeasurements(node) {
  node.clearMeasurements();
}
function resetTransformStyle(node) {
  var visualElement = node.options.visualElement;
  if (visualElement === null || visualElement === void 0 ? void 0 : visualElement.getProps().onBeforeLayoutMeasure) {
    visualElement.notifyBeforeLayoutMeasure();
  }
  node.resetTransform();
}
function finishAnimation(node) {
  node.finishAnimation();
  node.targetDelta = node.relativeTarget = node.target = void 0;
}
function resolveTargetDelta(node) {
  node.resolveTargetDelta();
}
function calcProjection(node) {
  node.calcProjection();
}
function resetRotation(node) {
  node.resetRotation();
}
function removeLeadSnapshots(stack) {
  stack.removeLeadSnapshot();
}
function mixAxisDelta(output, delta, p) {
  output.translate = mix(delta.translate, 0, p);
  output.scale = mix(delta.scale, 1, p);
  output.origin = delta.origin;
  output.originPoint = delta.originPoint;
}
function mixAxis(output, from, to, p) {
  output.min = mix(from.min, to.min, p);
  output.max = mix(from.max, to.max, p);
}
function mixBox(output, from, to, p) {
  mixAxis(output.x, from.x, to.x, p);
  mixAxis(output.y, from.y, to.y, p);
}
function hasOpacityCrossfade(node) {
  return node.animationValues && node.animationValues.opacityExit !== void 0;
}
var defaultLayoutTransition = {
  duration: 0.45,
  ease: [0.4, 0, 0.1, 1]
};
function mountNodeEarly(node, id) {
  var searchNode = node.root;
  for (var i = node.path.length - 1; i >= 0; i--) {
    if (Boolean(node.path[i].instance)) {
      searchNode = node.path[i];
      break;
    }
  }
  var searchElement = searchNode && searchNode !== node.root ? searchNode.instance : document;
  var element = searchElement.querySelector('[data-projection-id="'.concat(id, '"]'));
  if (element)
    node.mount(element, true);
}
function roundAxis(axis) {
  axis.min = Math.round(axis.min);
  axis.max = Math.round(axis.max);
}
function roundBox(box) {
  roundAxis(box.x);
  roundAxis(box.y);
}
export {
  createProjectionNode,
  mixAxis,
  mixAxisDelta,
  mixBox
};
//# sourceMappingURL=create-projection-node.js.map
