aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/PhysicsSimulationWeight.tsx
diff options
context:
space:
mode:
authorbrynnchernosky <56202540+brynnchernosky@users.noreply.github.com>2023-01-31 13:11:44 -0500
committerbrynnchernosky <56202540+brynnchernosky@users.noreply.github.com>2023-01-31 13:11:44 -0500
commit60ed47bf843704f2f4a4ccd152e15fb96a5c375e (patch)
tree7e1d212e95b28f1cea69dd5c25bbb5dd36e31ee5 /src/client/views/nodes/PhysicsSimulationWeight.tsx
parent6fba3c7fdaaed12d94dee359f520591e55cb76d8 (diff)
start converting weight file to class
Diffstat (limited to 'src/client/views/nodes/PhysicsSimulationWeight.tsx')
-rw-r--r--src/client/views/nodes/PhysicsSimulationWeight.tsx397
1 files changed, 180 insertions, 217 deletions
diff --git a/src/client/views/nodes/PhysicsSimulationWeight.tsx b/src/client/views/nodes/PhysicsSimulationWeight.tsx
index cc024f29a..d234c1395 100644
--- a/src/client/views/nodes/PhysicsSimulationWeight.tsx
+++ b/src/client/views/nodes/PhysicsSimulationWeight.tsx
@@ -1,6 +1,8 @@
+import React from "react";
import { useEffect, useState } from "react";
+import { render } from "react-dom";
import { IWallProps } from "./PhysicsSimulationWall";
-import { Wedge } from "./PhysicsSimulationWedge";
+import Wedge from "./PhysicsSimulationWedge";
export interface IForce {
description: string;
@@ -35,8 +37,6 @@ export interface IWeightProps {
setPendulumLength: (val: number) => any;
setStartPendulumAngle: (val: number) => any;
showAcceleration: boolean;
- mode: string;
- noMovement: boolean;
pendulumAngle: number;
setSketching: (val: boolean) => any;
showForces: boolean;
@@ -56,154 +56,121 @@ export interface IWeightProps {
wedgeHeight: number;
}
-export const Weight = (props: IWeightProps) => {
- const {
- adjustPendulumAngle,
- color,
- displayXPosition,
- displayYPosition,
- displayXVelocity,
- displayYVelocity,
- elasticCollisions,
- startForces,
- incrementTime,
- mass,
- paused,
- pendulum,
- pendulumLength,
- wedge,
- radius,
- mode,
- noMovement,
- pendulumAngle,
- reset,
- setSketching,
- setDisplayXAcceleration,
- setDisplayXPosition,
- setDisplayXVelocity,
- setDisplayYAcceleration,
- setDisplayYPosition,
- setDisplayYVelocity,
- setPaused,
- setPendulumAngle,
- setPendulumLength,
- setStartPendulumAngle,
- showAcceleration,
- showForces,
- showForceMagnitudes,
- showVelocity,
- startPosX,
- startPosY,
- startVelX,
- startVelY,
- timestepSize,
- updateDisplay,
- updatedForces,
- setUpdatedForces,
- walls,
- coefficientOfKineticFriction,
- wedgeWidth,
- wedgeHeight,
- } = props;
+interface IState {
+ dragging: boolean,
+ kineticFriction: boolean,
+ updatedStartPosX: number,
+ updatedStartPosY: number,
+ xPosition: number,
+ yPosition: number,
+ xVelocity: number,
+ yVelocity: number,
+}
+export default class Weight extends React.Component<IWeightProps, IState> {
+
+ constructor(props: any) {
+ super(props)
+ this.state = {
+ dragging: false,
+ kineticFriction: false,
+ updatedStartPosX: this.props.startPosX,
+ updatedStartPosY: this.props.startPosY,
+ xPosition: this.props.startPosX,
+ yPosition: this.props.startPosY,
+ xVelocity: this.props.startVelX ? this.props.startVelX: 0,
+ yVelocity: this.props.startVelY ? this.props.startVelY: 0,
+ }
+ }
// Constants
- const draggable = !wedge && mode == "Freeform";
- const epsilon = 0.0001;
-
- const forceOfGravity: IForce = {
+ draggable = !this.props.wedge;
+ epsilon = 0.0001;
+ forceOfGravity: IForce = {
description: "Gravity",
- magnitude: mass * 9.81,
+ magnitude: this.props.mass * 9.81,
directionInDegrees: 270,
};
- const xMax = window.innerWidth * 0.7;
- const xMin = 0;
- const yMax = window.innerHeight * 0.8;
- const yMin = 0;
-
- // State hooks
- const [dragging, setDragging] = useState(false);
- const [kineticFriction, setKineticFriction] = useState(false);
- const [updatedStartPosX, setUpdatedStartPosX] = useState(startPosX);
- const [updatedStartPosY, setUpdatedStartPosY] = useState(startPosY);
- const [xPosition, setXPosition] = useState(startPosX);
- const [xVelocity, setXVelocity] = useState(startVelX ?? 0);
- const [yPosition, setYPosition] = useState(startPosY);
- const [yVelocity, setYVelocity] = useState(startVelY ?? 0);
+ xMax = window.innerWidth * 0.7;
+ xMin = 0;
+ yMax = window.innerHeight * 0.8;
+ yMin = 0;
// Helper function to go between display and real values
const getDisplayYPos = (yPos: number) => {
- return yMax - yPos - 2 * radius + 5;
+ return this.yMax - yPos - 2 * this.props.radius + 5;
};
const getYPosFromDisplay = (yDisplay: number) => {
- return yMax - yDisplay - 2 * radius + 5;
+ return this.yMax - yDisplay - 2 * this.props.radius + 5;
};
// Set display values based on real values
const setYPosDisplay = (yPos: number) => {
- const displayPos = getDisplayYPos(yPos);
- setDisplayYPosition(Math.round(displayPos * 100) / 100);
+ const displayPos = this.getDisplayYPos(yPos);
+ this.props.setDisplayYPosition(Math.round(displayPos * 100) / 100)
};
const setXPosDisplay = (xPos: number) => {
- setDisplayXPosition(Math.round(xPos * 100) / 100);
+ this.props.setDisplayXPosition(Math.round(xPos * 100) / 100);
};
const setYVelDisplay = (yVel: number) => {
- setDisplayYVelocity((-1 * Math.round(yVel * 100)) / 100);
+ this.props.setDisplayYVelocity((-1 * Math.round(yVel * 100)) / 100);
};
const setXVelDisplay = (xVel: number) => {
- setDisplayXVelocity(Math.round(xVel * 100) / 100);
+ this.props.setDisplayXVelocity(Math.round(xVel * 100) / 100);
};
const setDisplayValues = (
- xPos: number = xPosition,
- yPos: number = yPosition,
- xVel: number = xVelocity,
- yVel: number = yVelocity
+ xPos: number = this.state.xPosition,
+ yPos: number = this.state.yPosition,
+ xVel: number = this.state.xVelocity,
+ yVel: number = this.state.yVelocity
) => {
- setYPosDisplay(yPos);
- setXPosDisplay(xPos);
- setYVelDisplay(yVel);
- setXVelDisplay(xVel);
- setDisplayYAcceleration(
- (-1 * Math.round(getNewAccelerationY(updatedForces) * 100)) / 100
+ this.setYPosDisplay(yPos);
+ this.setXPosDisplay(xPos);
+ this.setYVelDisplay(yVel);
+ this.setXVelDisplay(xVel);
+ this.props.setDisplayYAcceleration(
+ (-1 * Math.round(getNewAccelerationY(this.props.updatedForces) * 100)) / 100
);
- setDisplayXAcceleration(
- Math.round(getNewAccelerationX(updatedForces) * 100) / 100
+ this.props.setDisplayXAcceleration(
+ Math.round(getNewAccelerationX(this.props.updatedForces) * 100) / 100
);
};
// When display values updated by user, update real values
- useEffect(() => {
- if (updateDisplay.xDisplay != xPosition) {
- let x = updateDisplay.xDisplay;
- x = Math.max(0, x);
- x = Math.min(x, xMax - 2 * radius);
- setUpdatedStartPosX(x);
- setXPosition(x);
- setDisplayXPosition(x);
- }
-
- if (updateDisplay.yDisplay != getDisplayYPos(yPosition)) {
- let y = updateDisplay.yDisplay;
- y = Math.max(0, y);
- y = Math.min(y, yMax - 2 * radius);
- setDisplayYPosition(y);
- let coordinatePosition = getYPosFromDisplay(y);
- setUpdatedStartPosY(coordinatePosition);
- setYPosition(coordinatePosition);
- }
-
- if (displayXVelocity != xVelocity) {
- let x = displayXVelocity;
- setXVelocity(x);
- setDisplayXVelocity(x);
- }
-
- if (displayYVelocity != -yVelocity) {
- let y = displayYVelocity;
- setYVelocity(-y);
- setDisplayYVelocity(y);
+ componentDidUpdate(prevProps: Readonly<IWeightProps>, prevState: Readonly<IState>, snapshot?: any): void {
+ if (this.props.updateDisplay != prevProps.updateDisplay) {
+ if (this.props.updateDisplay.xDisplay != this.state.xPosition) {
+ let x = this.props.updateDisplay.xDisplay;
+ x = Math.max(0, x);
+ x = Math.min(x, this.xMax - 2 * this.props.radius);
+ this.setState({updatedStartPosX: x})
+ this.setState({xPosition: x})
+ this.props.setDisplayXPosition(x);
+ }
+
+ if (this.props.updateDisplay.yDisplay != this.getDisplayYPos(this.state.yPosition)) {
+ let y = this.props.updateDisplay.yDisplay;
+ y = Math.max(0, y);
+ y = Math.min(y, this.yMax - 2 * this.props.radius);
+ this.props.setDisplayYPosition(y);
+ let coordinatePosition = this.getYPosFromDisplay(y);
+ this.setState({updatedStartPosY: coordinatePosition})
+ this.setState({yPosition: coordinatePosition})
+ }
+
+ if (this.props.displayXVelocity != this.state.xVelocity) {
+ let x = this.props.displayXVelocity;
+ this.setState({xVelocity: x})
+ this.props.setDisplayXVelocity(x);
+ }
+
+ if (this.props.displayYVelocity != this.state.yVelocity) {
+ let y = this.props.displayYVelocity;
+ this.setState({yVelocity: -y})
+ this.props.setDisplayXVelocity(y);
+ }
}
- }, [updateDisplay]);
+ }
// Check for collisions and update
useEffect(() => {
@@ -264,7 +231,7 @@ export const Weight = (props: IWeightProps) => {
newXAcc +=
(force.magnitude *
Math.cos((force.directionInDegrees * Math.PI) / 180)) /
- mass;
+ this.props.mass;
});
return newXAcc;
};
@@ -276,7 +243,7 @@ export const Weight = (props: IWeightProps) => {
(-1 *
(force.magnitude *
Math.sin((force.directionInDegrees * Math.PI) / 180))) /
- mass;
+ this.props.mass;
});
return newYAcc;
};
@@ -287,11 +254,11 @@ export const Weight = (props: IWeightProps) => {
xVel: number,
yVel: number
) => {
- if (!pendulum) {
- return updatedForces;
+ if (!this.props.pendulum) {
+ return this.state.updatedForces;
}
- const x = xMax / 2 - xPos - radius;
- const y = yPos + radius + 5;
+ const x = this.xMax / 2 - xPos - this.props.radius;
+ const y = yPos + this.props.radius + 5;
let angle = (Math.atan(y / x) * 180) / Math.PI;
if (angle < 0) {
angle += 180;
@@ -306,8 +273,8 @@ export const Weight = (props: IWeightProps) => {
setPendulumLength(Math.sqrt(x * x + y * y));
const mag =
- mass * 9.81 * Math.cos((oppositeAngle * Math.PI) / 180) +
- (mass * (xVel * xVel + yVel * yVel)) / pendulumLength;
+ this.props.mass * 9.81 * Math.cos((oppositeAngle * Math.PI) / 180) +
+ (this.props.mass * (xVel * xVel + yVel * yVel)) / pendulumLength;
const forceOfTension: IForce = {
description: "Tension",
@@ -315,24 +282,24 @@ export const Weight = (props: IWeightProps) => {
directionInDegrees: angle,
};
- return [forceOfGravity, forceOfTension];
+ return [this.forceOfGravity, forceOfTension];
};
const getNewPosition = (pos: number, vel: number) => {
- return pos + vel * timestepSize;
+ return pos + vel * this.props.timestepSize;
};
const getNewVelocity = (vel: number, acc: number) => {
- return vel + acc * timestepSize;
+ return vel + acc * this.props.timestepSize;
};
const checkForCollisionsWithWall = () => {
let collision = false;
- const minX = xPosition;
- const maxX = xPosition + 2 * radius;
+ const minX = this.state.xPosition;
+ const maxX = this.state.xPosition + 2 * this.props.radius;
const containerWidth = window.innerWidth;
- if (xVelocity != 0) {
- walls.forEach((wall) => {
+ if (this.state.xVelocity != 0) {
+ this.props.walls.forEach((wall) => {
if (wall.angleInDegrees == 90) {
const wallX = (wall.xPos / 100) * window.innerWidth;
if (wall.xPos < 0.35) {
@@ -542,43 +509,39 @@ export const Weight = (props: IWeightProps) => {
setYPosDisplay(startPosY);
}, [startPosY]);
- return (
+ render () {
+ return (
<div style={{ zIndex: -1000 }}>
<div
className="weightContainer"
onPointerDown={(e) => {
- if (draggable) {
+ if (this.props.draggable) {
e.preventDefault();
- setPaused(true);
- setDragging(true);
+ this.props.setPaused(true);
+ this.setState({dragging: true});
setClickPositionX(e.clientX);
setClickPositionY(e.clientY);
- } else if (mode == "Review") {
- setSketching(true);
}
}}
onPointerMove={(e) => {
e.preventDefault();
- if (dragging) {
- let newY = yPosition + e.clientY - clickPositionY;
- if (newY > yMax - 2 * radius) {
- newY = yMax - 2 * radius;
+ if (this.state.dragging) {
+ let newY = this.state.yPosition + e.clientY - clickPositionY;
+ if (newY > this.yMax - 2 * this.props.radius) {
+ newY = this.yMax - 2 * this.props.radius;
}
- let newX = xPosition + e.clientX - clickPositionX;
- if (newX > xMax - 2 * radius) {
- newX = xMax - 2 * radius;
+ let newX = this.state.xPosition + e.clientX - clickPositionX;
+ if (newX > this.xMax - 2 * this.props.radius) {
+ newX = this.xMax - 2 * this.props.radius;
} else if (newX < 0) {
newX = 0;
}
-
- setXPosition(newX);
- setYPosition(newY);
- setUpdatedStartPosX(newX);
- setUpdatedStartPosY(newY);
- setDisplayYPosition(
- Math.round((yMax - 2 * radius - newY + 5) * 100) / 100
- );
+ this.setState({xPosition: newX})
+ this.setState({yPosition: newY})
+ this.setState({updatedStartPosX: newX})
+ this.setState({updatedStartPosY: newY})
+ this.setState({displayYPosition: Math.round((yMax - 2 * radius - newY + 5) * 100) / 100})
setClickPositionX(e.clientX);
setClickPositionY(e.clientY);
setDisplayValues();
@@ -591,20 +554,20 @@ export const Weight = (props: IWeightProps) => {
resetEverything();
}
setDragging(false);
- let newY = yPosition + e.clientY - clickPositionY;
- if (newY > yMax - 2 * radius) {
- newY = yMax - 2 * radius;
+ let newY = this.state.yPosition + e.clientY - clickPositionY;
+ if (newY > this.yMax - 2 * this.props.radius) {
+ newY = this.yMax - 2 * this.props.radius;
}
let newX = xPosition + e.clientX - clickPositionX;
- if (newX > xMax - 2 * radius) {
- newX = xMax - 2 * radius;
+ if (newX > this.xMax - 2 * this.props.radius) {
+ newX = this.xMax - 2 * this.props.radius;
} else if (newX < 0) {
newX = 0;
}
- if (pendulum) {
- const x = xMax / 2 - newX - radius;
- const y = newY + radius + 5;
+ if (this.state.pendulum) {
+ const x = this.xMax / 2 - newX - this.props.radius;
+ const y = newY + this.props.radius + 5;
let angle = (Math.atan(y / x) * 180) / Math.PI;
if (angle < 0) {
angle += 180;
@@ -615,20 +578,19 @@ export const Weight = (props: IWeightProps) => {
}
const pendulumLength = Math.sqrt(x * x + y * y);
- setPendulumAngle(oppositeAngle);
- setPendulumLength(Math.sqrt(x * x + y * y));
+ this.props.setPendulumAngle(oppositeAngle);
+ this.props.setPendulumLength(Math.sqrt(x * x + y * y));
const mag = 9.81 * Math.cos((oppositeAngle * Math.PI) / 180);
const forceOfTension: IForce = {
description: "Tension",
magnitude: mag,
directionInDegrees: angle,
};
-
- setKineticFriction(false);
- setXVelocity(startVelX ?? 0);
- setYVelocity(startVelY ?? 0);
+ this.setState({kineticFriction: false})
+ this.setState({xVelocity: startVelX ?? 0})
+ this.setState({yVelocity: startVelY ?? 0})
setDisplayValues();
- setUpdatedForces([forceOfGravity, forceOfTension]);
+ this.setState({updatedForces :[forceOfGravity, forceOfTension]});
}
}
}}
@@ -637,7 +599,7 @@ export const Weight = (props: IWeightProps) => {
<p className="weightLabel">{mass} kg</p>
</div>
</div>
- {pendulum && (
+ {this.state.pendulum && (
<div
className="rod"
style={{
@@ -648,45 +610,45 @@ export const Weight = (props: IWeightProps) => {
zIndex: -2,
}}
>
- <svg width={xMax + "px"} height={window.innerHeight + "px"}>
+ <svg width={this.xMax + "px"} height={window.innerHeight + "px"}>
<line
- x1={xPosition + radius}
- y1={yPosition + radius}
- x2={xMax / 2}
+ x1={this.state.xPosition + this.props.radius}
+ y1={this.state.yPosition + this.props.radius}
+ x2={this.xMax / 2}
y2={-5}
stroke={"#deb887"}
strokeWidth="10"
/>
</svg>
- {!dragging && (
+ {!this.state.dragging && (
<div>
<p
style={{
position: "absolute",
zIndex: 5,
- left: xPosition + "px",
- top: yPosition - 70 + "px",
+ left: this.state.xPosition + "px",
+ top: this.state.yPosition - 70 + "px",
backgroundColor: labelBackgroundColor,
}}
>
- {Math.round(pendulumLength)} m
+ {Math.round(this.props.pendulumLength)} m
</p>
<p
style={{
position: "absolute",
zIndex: -1,
- left: xMax / 2 + "px",
+ left: this.xMax / 2 + "px",
top: 30 + "px",
backgroundColor: labelBackgroundColor,
}}
>
- {Math.round(pendulumAngle * 100) / 100}°
+ {Math.round(this.props.pendulumAngle * 100) / 100}°
</p>
</div>
)}
</div>
)}
- {!dragging && showAcceleration && (
+ {!this.state.dragging && this.props.showAcceleration && (
<div>
<div
style={{
@@ -697,7 +659,7 @@ export const Weight = (props: IWeightProps) => {
top: 0,
}}
>
- <svg width={xMax + "px"} height={window.innerHeight + "px"}>
+ <svg width={this.xMax + "px"} height={window.innerHeight + "px"}>
<defs>
<marker
id="accArrow"
@@ -712,10 +674,10 @@ export const Weight = (props: IWeightProps) => {
</marker>
</defs>
<line
- x1={xPosition + radius}
- y1={yPosition + radius}
- x2={xPosition + radius + getNewAccelerationX(updatedForces) * 5}
- y2={yPosition + radius + getNewAccelerationY(updatedForces) * 5}
+ x1={this.state.xPosition + this.props.radius}
+ y1={this.state.yPosition + this.props.radius}
+ x2={this.state.xPosition + this.props.radius + getNewAccelerationX(this.state.updatedForces) * 5}
+ y2={this.state.yPosition + this.props.radius + getNewAccelerationY(this.state.updatedForces) * 5}
stroke={"green"}
strokeWidth="5"
markerEnd="url(#accArrow)"
@@ -726,15 +688,15 @@ export const Weight = (props: IWeightProps) => {
pointerEvents: "none",
position: "absolute",
left:
- xPosition +
- radius +
- getNewAccelerationX(updatedForces) * 5 +
+ this.state.xPosition +
+ this.props.radius +
+ getNewAccelerationX(this.state.updatedForces) * 5 +
25 +
"px",
top:
- yPosition +
- radius +
- getNewAccelerationY(updatedForces) * 5 +
+ this.state.yPosition +
+ this.props.radius +
+ getNewAccelerationY(this.state.updatedForces) * 5 +
25 +
"px",
zIndex: -1,
@@ -745,8 +707,8 @@ export const Weight = (props: IWeightProps) => {
{Math.round(
100 *
Math.sqrt(
- Math.pow(getNewAccelerationX(updatedForces) * 3, 2) +
- Math.pow(getNewAccelerationY(updatedForces) * 3, 2)
+ Math.pow(getNewAccelerationX(this.state.updatedForces) * 3, 2) +
+ Math.pow(getNewAccelerationY(this.state.updatedForces) * 3, 2)
)
) / 100}{" "}
m/s<sup>2</sup>
@@ -755,7 +717,7 @@ export const Weight = (props: IWeightProps) => {
</div>
</div>
)}
- {!dragging && showVelocity && (
+ {!this.state.dragging && this.props.showVelocity && (
<div>
<div
style={{
@@ -766,7 +728,7 @@ export const Weight = (props: IWeightProps) => {
top: 0,
}}
>
- <svg width={xMax + "px"} height={window.innerHeight + "px"}>
+ <svg width={this.xMax + "px"} height={window.innerHeight + "px"}>
<defs>
<marker
id="velArrow"
@@ -781,10 +743,10 @@ export const Weight = (props: IWeightProps) => {
</marker>
</defs>
<line
- x1={xPosition + radius}
- y1={yPosition + radius}
- x2={xPosition + radius + xVelocity * 3}
- y2={yPosition + radius + yVelocity * 3}
+ x1={this.state.xPosition + this.props.radius}
+ y1={this.state.yPosition + this.props.radius}
+ x2={this.state.xPosition + this.props.radius + this.state.xVelocity * 3}
+ y2={this.state.yPosition + this.props.radius + this.state.yVelocity * 3}
stroke={"blue"}
strokeWidth="5"
markerEnd="url(#velArrow)"
@@ -794,15 +756,15 @@ export const Weight = (props: IWeightProps) => {
style={{
pointerEvents: "none",
position: "absolute",
- left: xPosition + radius + xVelocity * 3 + 25 + "px",
- top: yPosition + radius + yVelocity * 3 + "px",
+ left: this.state.xPosition + this.props.radius + this.state.xVelocity * 3 + 25 + "px",
+ top: this.state.yPosition + this.props.radius + this.state.yVelocity * 3 + "px",
zIndex: -1,
lineHeight: 0.5,
}}
>
<p>
{Math.round(
- 100 * Math.sqrt(xVelocity * xVelocity + yVelocity * yVelocity)
+ 100 * Math.sqrt(this.state.xVelocity**2 + this.state.yVelocity**2)
) / 100}{" "}
m/s
</p>
@@ -810,14 +772,14 @@ export const Weight = (props: IWeightProps) => {
</div>
</div>
)}
- {!dragging &&
- showForces &&
- updatedForces.map((force, index) => {
- if (force.magnitude < epsilon) {
+ {!this.state.dragging &&
+ this.props.showForces &&
+ this.props.updatedForces.map((force, index) => {
+ if (force.magnitude < this.epsilon) {
return;
}
- let arrowStartY: number = yPosition + radius;
- const arrowStartX: number = xPosition + radius;
+ let arrowStartY: number = this.state.yPosition + this.props.radius;
+ const arrowStartX: number = this.state.xPosition + this.props.radius;
let arrowEndY: number =
arrowStartY -
Math.abs(force.magnitude) *
@@ -843,10 +805,10 @@ export const Weight = (props: IWeightProps) => {
} else {
labelTop -= 40;
}
- labelTop = Math.min(labelTop, yMax + 50);
- labelTop = Math.max(labelTop, yMin);
- labelLeft = Math.min(labelLeft, xMax - 60);
- labelLeft = Math.max(labelLeft, xMin);
+ labelTop = Math.min(labelTop, this.yMax + 50);
+ labelTop = Math.max(labelTop, this.yMin);
+ labelLeft = Math.min(labelLeft, this.xMax - 60);
+ labelLeft = Math.max(labelLeft, this.xMin);
return (
<div key={index}>
@@ -908,5 +870,6 @@ export const Weight = (props: IWeightProps) => {
);
})}
</div>
- );
+ );
+ }
};