: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
prevProps.layoutDependency !== layoutDependency ||
layoutDependency === undefined) {
if (prevProps.isPresent !== isPresent) {
else if (!projection.relegate()) {
* If there's another stack member taking over from this one,
* it's in charge of the exit animation and therefore should
* be in charge of the safe to remove. Otherwise we call it here.
frame_frame.postRender(() => {
const stack = projection.getStack();
if (!stack || !stack.members.length) {
const { projection } = this.props.visualElement;
projection.root.didUpdate();
microtask.postRender(() => {
if (!projection.currentAnimation && projection.isLead()) {
const { visualElement, layoutGroup, switchLayoutGroup: promoteContext, } = this.props;
const { projection } = visualElement;
projection.scheduleCheckAfterUnmount();
if (layoutGroup && layoutGroup.group)
layoutGroup.group.remove(projection);
if (promoteContext && promoteContext.deregister)
promoteContext.deregister(projection);
const { safeToRemove } = this.props;
safeToRemove && safeToRemove();
function MeasureLayout(props) {
const [isPresent, safeToRemove] = usePresence();
const layoutGroup = (0,external_React_.useContext)(LayoutGroupContext);
return ((0,external_ReactJSXRuntime_namespaceObject.jsx)(MeasureLayoutWithContext, { ...props, layoutGroup: layoutGroup, switchLayoutGroup: (0,external_React_.useContext)(SwitchLayoutGroupContext), isPresent: isPresent, safeToRemove: safeToRemove }));
const defaultScaleCorrectors = {
"borderBottomLeftRadius",
"borderBottomRightRadius",
borderTopLeftRadius: correctBorderRadius,
borderTopRightRadius: correctBorderRadius,
borderBottomLeftRadius: correctBorderRadius,
borderBottomRightRadius: correctBorderRadius,
boxShadow: correctBoxShadow,
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/projection/animation/mix-values.mjs
const borders = ["TopLeft", "TopRight", "BottomLeft", "BottomRight"];
const numBorders = borders.length;
const asNumber = (value) => typeof value === "string" ? parseFloat(value) : value;
const isPx = (value) => typeof value === "number" || px.test(value);
function mixValues(target, follow, lead, progress, shouldCrossfadeOpacity, isOnlyMember) {
if (shouldCrossfadeOpacity) {
target.opacity = mixNumber(0,
// TODO Reinstate this if only child
lead.opacity !== undefined ? lead.opacity : 1, easeCrossfadeIn(progress));
target.opacityExit = mixNumber(follow.opacity !== undefined ? follow.opacity : 1, 0, easeCrossfadeOut(progress));
target.opacity = mixNumber(follow.opacity !== undefined ? follow.opacity : 1, lead.opacity !== undefined ? lead.opacity : 1, progress);
for (let i = 0; i < numBorders; i++) {
const borderLabel = `border${borders[i]}Radius`;
let followRadius = getRadius(follow, borderLabel);
let leadRadius = getRadius(lead, borderLabel);
if (followRadius === undefined && leadRadius === undefined)
followRadius || (followRadius = 0);
leadRadius || (leadRadius = 0);
const canMix = followRadius === 0 ||
isPx(followRadius) === isPx(leadRadius);
target[borderLabel] = Math.max(mixNumber(asNumber(followRadius), asNumber(leadRadius), progress), 0);
if (percent.test(leadRadius) || percent.test(followRadius)) {
target[borderLabel] += "%";
target[borderLabel] = leadRadius;
if (follow.rotate || lead.rotate) {
target.rotate = mixNumber(follow.rotate || 0, lead.rotate || 0, progress);
function getRadius(values, radiusName) {
return values[radiusName] !== undefined
// * We only want to mix the background color if there's a follow element
// * that we're not crossfading opacity between. For instance with switch
// * AnimateSharedLayout animations, this helps the illusion of a continuous
// * element being animated but also cuts down on the number of paints triggered
// * for elements where opacity is doing that work for us.
// latestLeadValues.backgroundColor &&
// latestFollowValues.backgroundColor
// * This isn't ideal performance-wise as mixColor is creating a new function every frame.
// * We could probably create a mixer that runs at the start of the animation but
// * the idea behind the crossfader is that it runs dynamically between two potentially
// * changing targets (ie opacity or borderRadius may be animating independently via variants)
// leadState.backgroundColor = followState.backgroundColor = mixColor(
// latestFollowValues.backgroundColor as string,
// latestLeadValues.backgroundColor as string
const easeCrossfadeIn = compress(0, 0.5, circOut);
const easeCrossfadeOut = compress(0.5, 0.95, noop_noop);
function compress(min, max, easing) {
// Could replace ifs with clamp
return easing(progress(min, max, p));
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/projection/geometry/copy.mjs
* Reset an axis to the provided origin box.
* This is a mutative operation.
function copyAxisInto(axis, originAxis) {
axis.min = originAxis.min;
axis.max = originAxis.max;
* Reset a box to the provided origin box.
* This is a mutative operation.
function copyBoxInto(box, originBox) {
copyAxisInto(box.x, originBox.x);
copyAxisInto(box.y, originBox.y);
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/projection/geometry/delta-remove.mjs
* Remove a delta from a point. This is essentially the steps of applyPointDelta in reverse
function removePointDelta(point, translate, scale, originPoint, boxScale) {
point = scalePoint(point, 1 / scale, originPoint);
if (boxScale !== undefined) {
point = scalePoint(point, 1 / boxScale, originPoint);
* Remove a delta from an axis. This is essentially the steps of applyAxisDelta in reverse
function removeAxisDelta(axis, translate = 0, scale = 1, origin = 0.5, boxScale, originAxis = axis, sourceAxis = axis) {
if (percent.test(translate)) {
translate = parseFloat(translate);
const relativeProgress = mixNumber(sourceAxis.min, sourceAxis.max, translate / 100);
translate = relativeProgress - sourceAxis.min;
if (typeof translate !== "number")
let originPoint = mixNumber(originAxis.min, originAxis.max, origin);
originPoint -= translate;
axis.min = removePointDelta(axis.min, translate, scale, originPoint, boxScale);
axis.max = removePointDelta(axis.max, translate, scale, originPoint, boxScale);
* Remove a transforms from an axis. This is essentially the steps of applyAxisTransforms in reverse
* and acts as a bridge between motion values and removeAxisDelta
function removeAxisTransforms(axis, transforms, [key, scaleKey, originKey], origin, sourceAxis) {
removeAxisDelta(axis, transforms[key], transforms[scaleKey], transforms[originKey], transforms.scale, origin, sourceAxis);
* The names of the motion values we want to apply as translation, scale and origin.
const delta_remove_xKeys = ["x", "scaleX", "originX"];
const delta_remove_yKeys = ["y", "scaleY", "originY"];
* Remove a transforms from an box. This is essentially the steps of applyAxisBox in reverse
* and acts as a bridge between motion values and removeAxisDelta
function removeBoxTransforms(box, transforms, originBox, sourceBox) {
removeAxisTransforms(box.x, transforms, delta_remove_xKeys, originBox ? originBox.x : undefined, sourceBox ? sourceBox.x : undefined);
removeAxisTransforms(box.y, transforms, delta_remove_yKeys, originBox ? originBox.y : undefined, sourceBox ? sourceBox.y : undefined);
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/projection/geometry/utils.mjs
function isAxisDeltaZero(delta) {
return delta.translate === 0 && delta.scale === 1;
function isDeltaZero(delta) {
return isAxisDeltaZero(delta.x) && isAxisDeltaZero(delta.y);
function boxEquals(a, b) {
return (a.x.min === b.x.min &&
function boxEqualsRounded(a, b) {
return (Math.round(a.x.min) === Math.round(b.x.min) &&
Math.round(a.x.max) === Math.round(b.x.max) &&
Math.round(a.y.min) === Math.round(b.y.min) &&
Math.round(a.y.max) === Math.round(b.y.max));
function aspectRatio(box) {
return calcLength(box.x) / calcLength(box.y);
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/projection/shared/stack.mjs
addUniqueItem(this.members, node);
removeItem(this.members, node);
if (node === this.prevLead) {
this.prevLead = undefined;
if (node === this.lead) {
const prevLead = this.members[this.members.length - 1];
const indexOfNode = this.members.findIndex((member) => node === member);
* Find the next projection node that is present
for (let i = indexOfNode; i >= 0; i--) {
const member = this.members[i];
if (member.isPresent !== false) {
promote(node, preserveFollowOpacity) {
const prevLead = this.lead;
this.prevLead = prevLead;
prevLead.instance && prevLead.scheduleRender();
node.resumeFrom = prevLead;
if (preserveFollowOpacity) {
node.resumeFrom.preserveOpacity = true;
node.snapshot = prevLead.snapshot;
node.snapshot.latestValues =
prevLead.animationValues || prevLead.latestValues;
if (node.root && node.root.isUpdating) {
node.isLayoutDirty = true;
const { crossfade } = node.options;
if (crossfade === false) {
* - Test border radius when previous node was deleted
* - Shared between element A in scrolled container and element B (scroll stays the same or changes)
* - Shared between element A in transformed container and element B (transform stays the same or changes)
* - Shared between element A in scrolled page and element B (scroll stays the same or changes)
* - Crossfade opacity of root nodes
* - layoutId changes after animation
* - layoutId changes mid animation
exitAnimationComplete() {
this.members.forEach((node) => {
const { options, resumingFrom } = node;
options.onExitComplete && options.onExitComplete();
resumingFrom.options.onExitComplete &&
resumingFrom.options.onExitComplete();
this.members.forEach((node) => {
node.instance && node.scheduleRender(false);
* Clear any leads that have been removed this render to prevent them from being
* used in future animations and to prevent memory leaks
if (this.lead && this.lead.snapshot) {
this.lead.snapshot = undefined;
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/projection/styles/transform.mjs
function buildProjectionTransform(delta, treeScale, latestTransform) {
* The translations we use to calculate are always relative to the viewport coordinate space.
* But when we apply scales, we also scale the coordinate space of an element and its children.
* For instance if we have a treeScale (the culmination of all parent scales) of 0.5 and we need
* to move an element 100 pixels, we actually need to move it 200 in within that scaled space.
const xTranslate = delta.x.translate / treeScale.x;
const yTranslate = delta.y.translate / treeScale.y;
const zTranslate = (latestTransform === null || latestTransform === void 0 ? void 0 : latestTransform.z) || 0;
if (xTranslate || yTranslate || zTranslate) {
transform = `translate3d(${xTranslate}px, ${yTranslate}px, ${zTranslate}px) `;
* Apply scale correction for the tree transform.
* This will apply scale to the screen-orientated axes.
if (treeScale.x !== 1 || treeScale.y !== 1) {
transform += `scale(${1 / treeScale.x}, ${1 / treeScale.y}) `;
const { transformPerspective, rotate, rotateX, rotateY, skewX, skewY } = latestTransform;
if (transformPerspective)
transform = `perspective(${transformPerspective}px) ${transform}`;
transform += `rotate(${rotate}deg) `;
transform += `rotateX(${rotateX}deg) `;
transform += `rotateY(${rotateY}deg) `;
transform += `skewX(${skewX}deg) `;
transform += `skewY(${skewY}deg) `;
* Apply scale to match the size of the element to the size we want it.
* This will apply scale to the element-orientated axes.
const elementScaleX = delta.x.scale * treeScale.x;
const elementScaleY = delta.y.scale * treeScale.y;
if (elementScaleX !== 1 || elementScaleY !== 1) {
transform += `scale(${elementScaleX}, ${elementScaleY})`;
return transform || "none";
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/render/utils/compare-by-depth.mjs
const compareByDepth = (a, b) => a.depth - b.depth;
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/render/utils/flat-tree.mjs
addUniqueItem(this.children, child);
removeItem(this.children, child);
this.isDirty && this.children.sort(compareByDepth);
this.children.forEach(callback);
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/utils/delay.mjs
function delay(callback, timeout) {
const start = time.now();
const checkElapsed = ({ timestamp }) => {
const elapsed = timestamp - start;
if (elapsed >= timeout) {
cancelFrame(checkElapsed);
callback(elapsed - timeout);
frame_frame.read(checkElapsed, true);
return () => cancelFrame(checkElapsed);