Add settings page for managing forecasting API key and URL via UI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-20 14:37:36 +00:00
parent cae411eae7
commit 1c411e402e
19809 changed files with 1962608 additions and 97 deletions

View file

@ -0,0 +1,124 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.AnimatedItems = AnimatedItems;
exports.useAnimationCallbacks = useAnimationCallbacks;
var _react = _interopRequireWildcard(require("react"));
var React = _react;
var _JavascriptAnimate = require("./JavascriptAnimate");
var _useAnimationId = require("../util/useAnimationId");
var _matchBy = require("./matchBy");
var _useAnimationStartSnapshot = require("./useAnimationStartSnapshot");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
/**
* Hook that tracks animation state and provides callbacks for animation start/end.
*
* @param onAnimationStart optional callback to call when animation starts
* @param onAnimationEnd optional callback to call when animation ends
*/
function useAnimationCallbacks(onAnimationStart, onAnimationEnd) {
var _useState = (0, _react.useState)(false),
_useState2 = _slicedToArray(_useState, 2),
isAnimating = _useState2[0],
setIsAnimating = _useState2[1];
var handleAnimationStart = (0, _react.useCallback)(() => {
if (typeof onAnimationStart === 'function') {
onAnimationStart();
}
setIsAnimating(true);
}, [onAnimationStart]);
var handleAnimationEnd = (0, _react.useCallback)(() => {
if (typeof onAnimationEnd === 'function') {
onAnimationEnd();
}
setIsAnimating(false);
}, [onAnimationEnd]);
return {
isAnimating,
handleAnimationStart,
handleAnimationEnd
};
}
/**
* A function that interpolates animation items at a given time.
* This function receives an array of changes, and must "unwrap" them
* and interpolate appropriate values and return the result which Recharts will then render.
*
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animations guide}
*
* @param items The tagged animation items describing what changed, or `null` on the very first render
* (entrance animation). Each item is self-describing:
* - `{ status: 'matched', prev, next }` interpolate between `prev` and `next`
* - `{ status: 'added', next }` animate in from a computed entry position
* - `{ status: 'removed', prev }` animate out to a computed exit position
*
* At `animationElapsedTime = 1`, removed items should be excluded from the result.
*
* @param animationElapsedTime A normalized time value (0 = start, 1 = end)
* @param layout of the chart, useful for deciding the direction of animation
* @returns The interpolated items at time animationElapsedTime
*
* @since 3.9
*/
/**
* A reusable animation wrapper for array-based chart data.
*
* Encapsulates the common animation pattern shared by Bar, Scatter, Funnel, Pie,
* Radar, RadialBar, Area, and Line:
* 1. Track previous items in a ref
* 2. Wrap in JavascriptAnimate
* 3. Update ref when animationElapsedTime > 0
*
* @since 3.9
*/
function AnimatedItems(props) {
var _animationStartItems$;
var animationInput = props.animationInput,
animationIdPrefix = props.animationIdPrefix,
items = props.items,
previousItemsRef = props.previousItemsRef,
isAnimationActive = props.isAnimationActive,
animationBegin = props.animationBegin,
animationDuration = props.animationDuration,
animationEasing = props.animationEasing,
onAnimationStart = props.onAnimationStart,
onAnimationEnd = props.onAnimationEnd,
animationInterpolateFn = props.animationInterpolateFn,
animationMatchBy = props.animationMatchBy,
shouldUpdatePreviousRef = props.shouldUpdatePreviousRef,
children = props.children,
layout = props.layout;
var animationId = (0, _useAnimationId.useAnimationId)(animationInput, animationIdPrefix);
var animationStartItems = (0, _useAnimationStartSnapshot.useAnimationStartSnapshot)(animationId, previousItemsRef);
var rawPrevItems = (_animationStartItems$ = animationStartItems.startValue) !== null && _animationStartItems$ !== void 0 ? _animationStartItems$ : null;
var animationItems = (0, _matchBy.matchAnimationItems)(rawPrevItems, items, animationMatchBy !== null && animationMatchBy !== void 0 ? animationMatchBy : _matchBy.matchByIndex);
return /*#__PURE__*/React.createElement(_JavascriptAnimate.JavascriptAnimate, {
animationId: animationId,
begin: animationBegin,
duration: animationDuration,
isActive: isAnimationActive,
easing: animationEasing,
onAnimationEnd: onAnimationEnd,
onAnimationStart: onAnimationStart,
key: animationId
}, animationElapsedTime => {
var isEntrance = rawPrevItems == null;
var stepData = items == null ? items : animationInterpolateFn(animationItems, animationElapsedTime, layout);
var canUpdate = shouldUpdatePreviousRef ? shouldUpdatePreviousRef(animationElapsedTime) : animationElapsedTime > 0;
animationStartItems.syncStepValue(stepData, animationElapsedTime, canUpdate);
if (stepData == null) {
return null;
}
return children(stepData, animationElapsedTime, isEntrance);
});
}

View file

@ -0,0 +1 @@
"use strict";

View file

@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.animationControllerImpl = void 0;
/**
* JavaScript animations require trigger and repaint as soon as possible,
* so this class uses the timeoutController to trigger updates as quickly as the controller allows.
*
* JavaScript animation progress is represented as a stream of values. The exact type depends on the animationHandle type.
* Each individual consumer is then responsible for mapping those values onto a React component.
*/
var animationControllerImpl = (timeoutController, animationHandle, listener) => {
var cancellable;
var nextUpdate = now => {
var timeRemaining = animationHandle.tick(now);
if (animationHandle.getState() === 'active') {
listener(animationHandle.getInterpolated());
if (animationHandle.getProgress() === 1) {
animationHandle.complete();
cancellable = undefined;
return;
}
cancellable = timeoutController.setTimeout(nextUpdate, timeRemaining);
return;
}
cancellable = timeoutController.setTimeout(nextUpdate, timeRemaining);
};
cancellable = timeoutController.setTimeout(nextUpdate, 0);
return () => {
var _cancellable;
return (_cancellable = cancellable) === null || _cancellable === void 0 ? void 0 : _cancellable();
};
};
exports.animationControllerImpl = animationControllerImpl;

View file

@ -0,0 +1,273 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.JavascriptAnimation = exports.CSSTransitionAnimation = void 0;
var _DataUtils = require("../util/DataUtils");
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // eslint-disable-next-line max-classes-per-file
var INIT = 'init';
var PENDING = 'pending';
var ACTIVE = 'active';
var COMPLETED = 'completed';
function duration(time) {
return Math.max(0, time);
}
class RechartsAnimation {
/**
* Returns the absolute time after the animationBegin delay has been completed,
* and when the animationDuration started ticking.
*/
getAnimationStartedTime() {
return this.animationStartedTime;
}
/**
* Returns the absolute time of when the animation began - now it will wait for {animationBegin} ms before the transition starts
*/
getBeginStartedTime() {
return this.beginStartedTime;
}
constructor(param) {
var _param$onAnimationSta;
_defineProperty(this, "state", INIT);
this.animationId = param.animationId;
this.onAnimationEnd = param.onAnimationEnd;
this.animationDuration = duration(param.animationDuration);
this.animationBegin = duration(param.animationBegin);
this.progress = 0;
this.from = param.from;
this.to = param.to;
this.easing = param.easing;
// Mimic what the previous animationManager was doing - call onAnimationStart immediately and synchronously
(_param$onAnimationSta = param.onAnimationStart) === null || _param$onAnimationSta === void 0 || _param$onAnimationSta.call(param);
}
/**
* Returns the state machine current state
* - `init`: animation had just been created. It immediately calls `onAnimationStart`
* - `pending`: animation is now paused for `animationBegin` milliseconds until the transition begins
* - `active`: animation is transitioning items on screen
* - `completed`: animation has completed its transition and executed `onAnimationEnd`.
* This state is final and the animation is no longer allowed to transition to other states.
*/
getState() {
return this.state;
}
/**
* Returns the easing input or function
*/
getEasing() {
return this.easing;
}
/**
* Returns the configuration - the duration of the transition.
* Does not change in time, does not change when state changes, this is a static value.
*/
getAnimationDuration() {
return this.animationDuration;
}
/**
* Sets the current time of the animation. The animation sets its internal state and progress accordingly.
* This is current, absolute time; not additive!
* This allows you to essentially "travel back in time" based on the value you pass in here.
*
* Returns the (relative) time remaining until the current activity is over.
* Meaning: if the state is in a middle of a delay, returns the time left until the delay is finished.
* If the state is in the middle of a transition, returns time left until that transition is complete.
* This is useful because it's the same number you can take and put into setTimeout(fn, X)
* as that's how much time we need to wait until the next state transition happens.
*/
tick(now) {
if (this.getState() === INIT) {
this.state = PENDING;
this.beginStartedTime = now;
return this.animationBegin;
}
if (this.getState() === PENDING) {
if (this.beginStartedTime == null) {
throw new Error();
}
var _timeElapsed = now - this.beginStartedTime;
if (_timeElapsed >= this.animationBegin) {
this.state = ACTIVE;
this.animationStartedTime = now;
// The state flipped just now so the elapsed time is zero
return this.nextAnimationUpdate(0);
}
return duration(this.animationBegin - _timeElapsed);
}
if (this.getState() === ACTIVE) {
if (this.animationStartedTime == null) {
throw new Error();
}
var _timeElapsed2 = now - this.animationStartedTime;
this.setProgress(_timeElapsed2 / this.animationDuration);
return this.nextAnimationUpdate(_timeElapsed2);
}
// state === COMPLETED, nothing interesting is going to happen
return 0;
}
setProgress(newProgress) {
this.progress = Math.min(1, Math.max(0, newProgress));
}
/**
* Returns an abstract "progress" which is number between 0 and 1 which shows the distance of transition.
* This progress depends on the animation state:
* - `init`: 0
* - `pending`: 0
* - `active`: transitioning between [0, 1] based on the time elapsed
* - `completed`: 1
*
* The progress is hard-capped to be between 0 and 1 (inclusive) to avoid overshooting caused by coarse timers.
* For this reason, the easing function must be applied _after_ this animation state,
* so that one has a chance to construct dynamic "overshoot" animations.
*
* The progress is linear with time.
* If you wish for easing, use `getInterpolated()` instead.
*/
getProgress() {
return this.progress;
}
/**
* Completes the animation. Completed animation:
* - cannot be manipulated anymore
* - its progress is set to 1
* - tick function doesn't do anything
* - getState() always returns 'completed'
*/
complete() {
this.progress = 1;
if (this.state === 'active') {
var _this$onAnimationEnd;
// Do not call callbacks if the animation was interrupted before it even started!
(_this$onAnimationEnd = this.onAnimationEnd) === null || _this$onAnimationEnd === void 0 || _this$onAnimationEnd.call(this);
}
this.state = COMPLETED;
}
/**
* Returns the starting value of the animation.
* Does not include progress, easing, interpolation, none of that - just the static starting value
*/
getFrom() {
return this.from;
}
/**
* Returns the end value of the animation.
* Does not include progress, easing, interpolation, none of that - just the static end value
*/
getTo() {
return this.to;
}
/**
* Unique identifier of an animation
*/
getAnimationId() {
return this.animationId;
}
/**
* Returns the configuration - the duration of delay in between animation initialization, and transition.
* Does not change in time, does not change when state changes, this is a static value.
*/
getAnimationBegin() {
return this.animationBegin;
}
/**
* Returns value of the transition at the current time.
* The exact details differ based on the animation type
*/
/**
* Returns the duration of time of when the controller should ask for the next update
*/
}
/**
* Animation handle representing a Javascript-based animation.
* This animation requires one render cycle for each frame, and it calls setTimeout as quickly as possible
*
* @since 3.9
*/
class JavascriptAnimation extends RechartsAnimation {
// eslint-disable-next-line class-methods-use-this
nextAnimationUpdate() {
/*
* JavaScript-based animations have to update as soon as possible,
* so we return 0 here to indicate that the next update should be scheduled immediately
* and it should trigger render on every occasion.
*/
return 0;
}
/**
* Returns value of the animation after its easing function had been applied.
* This value, unlike getProgress(), can escape the [0..1] range
* because this is entirely within the easing function control. Spring typically does this.
*/
getInterpolated() {
return this.easing((0, _DataUtils.interpolate)(this.getFrom(), this.getTo(), this.getProgress()));
}
}
/**
* Animation handle representing a CSS transition.
* This animation requires only one render, and the actual transition is then handled by the browser.
*
* @since 3.9
*/
exports.JavascriptAnimation = JavascriptAnimation;
class CSSTransitionAnimation extends RechartsAnimation {
nextAnimationUpdate(timeElapsed) {
/**
* CSS transitions do not need DOM updates past the initial render
* so here we just instruct the controller to wait until the animation duration is over.
*/
return duration(this.animationDuration - timeElapsed);
}
/**
* Returns the final value of the animation (the `to`).
*
* CSS transitions leave both interpolation and easing to the browser,
* so all we need to do here is return the final state
* and let browser handle the rest.
*/
getInterpolated() {
return this.getTo();
}
}
/**
* Recharts animation state machine.
*
* Possible transitions are:
* - `init`: starting state - `onAnimationStart` executes
* - `init` to `pending` - `animationBegin` duration begins
* - `pending` to `active` - `animationDuration` duration begins, timer ticks decide the progress
* - `active` to `completed` - `onAnimationEnd` executes
*
* The state always moves in this direction, cannot move backwards.
*
* The animation queue is static and consists of four elements:
* - `onAnimationStart`: function that is called when the animation is created
* - `animationBegin`: delay between `onAnimationStart` and the transition
* - the transition itself, takes `animationDuration` ms to finish
* - `onAnimationEnd`: function that is called when the animation is moving from `active` to `completed`
*
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animation guide}
*
* @since 3.9
*/
exports.CSSTransitionAnimation = CSSTransitionAnimation;

View file

@ -0,0 +1,107 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CSSTransitionAnimate = CSSTransitionAnimate;
exports.extractCssEasing = extractCssEasing;
var _react = require("react");
var _DataUtils = require("../util/DataUtils");
var _resolveDefaultProps = require("../util/resolveDefaultProps");
var _useAnimationController = require("./useAnimationController");
var _util = require("./util");
var _Global = require("../util/Global");
var _usePrefersReducedMotion = require("../util/usePrefersReducedMotion");
var _AnimationHandle = require("./AnimationHandle");
var _timeoutController = require("./timeoutController");
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
var defaultProps = {
begin: 0,
duration: 1000,
easing: 'ease',
isActive: true,
canBegin: true,
onAnimationEnd: () => {},
onAnimationStart: () => {}
};
function extractCssEasing(easingInput) {
if (easingInput === 'spring' || typeof easingInput !== 'string') {
return undefined;
}
return easingInput;
}
function CSSTransitionAnimate(outsideProps) {
var props = (0, _resolveDefaultProps.resolveDefaultProps)(outsideProps, defaultProps);
var animationId = props.animationId,
from = props.from,
to = props.to,
attributeName = props.attributeName,
isActiveProp = props.isActive,
canBegin = props.canBegin,
duration = props.duration,
easing = props.easing,
begin = props.begin,
onAnimationEnd = props.onAnimationEnd,
onAnimationStartFromProps = props.onAnimationStart,
children = props.children;
var prefersReducedMotion = (0, _usePrefersReducedMotion.usePrefersReducedMotion)();
var isActive = isActiveProp === 'auto' ? !_Global.Global.isSsr && !prefersReducedMotion : isActiveProp;
var animationController = (0, _useAnimationController.useAnimationController)(props.animationController);
var _useState = (0, _react.useState)(() => {
if (!isActive) {
return to;
}
return from;
}),
_useState2 = _slicedToArray(_useState, 2),
style = _useState2[0],
setStyle = _useState2[1];
var initialized = (0, _react.useRef)(false);
var onAnimationStart = (0, _react.useCallback)(() => {
setStyle(from);
onAnimationStartFromProps();
}, [from, onAnimationStartFromProps]);
(0, _react.useEffect)(() => {
if (!isActive || !canBegin) {
return _DataUtils.noop;
}
initialized.current = true;
var timeoutController = new _timeoutController.RequestAnimationFrameTimeoutController();
var animation = new _AnimationHandle.CSSTransitionAnimation({
animationId: animationId + attributeName,
easing,
animationDuration: duration,
animationBegin: begin,
onAnimationStart,
onAnimationEnd,
from,
to
});
return animationController(timeoutController, animation, setStyle);
}, [isActive, canBegin, duration, easing, begin, onAnimationStart, onAnimationEnd, animationController, to, from, animationId, attributeName]);
if (!isActive) {
return children({
[attributeName]: to
});
}
if (!canBegin) {
return children({
[attributeName]: from
});
}
if (initialized.current) {
var transition = (0, _util.getTransitionVal)([attributeName], duration, easing);
return children({
transition,
[attributeName]: style
});
}
return children({
[attributeName]: from
});
}

View file

@ -0,0 +1,75 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.JavascriptAnimate = JavascriptAnimate;
var _react = require("react");
var _DataUtils = require("../util/DataUtils");
var _resolveDefaultProps = require("../util/resolveDefaultProps");
var _easing = require("./easing");
var _useAnimationController = require("./useAnimationController");
var _Global = require("../util/Global");
var _usePrefersReducedMotion = require("../util/usePrefersReducedMotion");
var _AnimationHandle = require("./AnimationHandle");
var _timeoutController = require("./timeoutController");
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
var defaultJavascriptAnimateProps = {
begin: 0,
duration: 1000,
easing: 'ease',
isActive: true,
canBegin: true,
onAnimationEnd: () => {},
onAnimationStart: () => {}
};
var from = 0;
var to = 1;
function JavascriptAnimate(outsideProps) {
var props = (0, _resolveDefaultProps.resolveDefaultProps)(outsideProps, defaultJavascriptAnimateProps);
var animationId = props.animationId,
isActiveProp = props.isActive,
canBegin = props.canBegin,
duration = props.duration,
easing = props.easing,
begin = props.begin,
onAnimationEnd = props.onAnimationEnd,
onAnimationStart = props.onAnimationStart,
children = props.children;
var prefersReducedMotion = (0, _usePrefersReducedMotion.usePrefersReducedMotion)();
var isActive = isActiveProp === 'auto' ? !_Global.Global.isSsr && !prefersReducedMotion : isActiveProp;
var animationController = (0, _useAnimationController.useAnimationController)(props.animationController);
var _useState = (0, _react.useState)(isActive ? from : to),
_useState2 = _slicedToArray(_useState, 2),
style = _useState2[0],
setStyle = _useState2[1];
(0, _react.useEffect)(() => {
if (!isActive) {
setStyle(to);
}
}, [isActive]);
(0, _react.useEffect)(() => {
var easingFunction = (0, _easing.createEasingFunction)(easing);
if (!isActive || !canBegin || easingFunction == null) {
return _DataUtils.noop;
}
var timeoutController = new _timeoutController.RequestAnimationFrameTimeoutController();
var animation = new _AnimationHandle.JavascriptAnimation({
animationId,
easing: easingFunction,
animationDuration: duration,
animationBegin: begin,
onAnimationStart,
onAnimationEnd,
from,
to
});
return animationController(timeoutController, animation, setStyle);
}, [animationController, animationId, isActive, canBegin, duration, easing, begin, onAnimationStart, onAnimationEnd]);
return children(Number(style));
}

183
frontend/node_modules/recharts/lib/animation/easing.js generated vendored Normal file
View file

@ -0,0 +1,183 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createSpringEasing = exports.createEasingFunction = exports.configBezier = exports.ACCURACY = void 0;
var ACCURACY = exports.ACCURACY = 1e-4;
var cubicBezierFactor = (c1, c2) => [0, 3 * c1, 3 * c2 - 6 * c1, 3 * c1 - 3 * c2 + 1];
var evaluatePolynomial = (params, animationElapsedTime) => params.map((param, i) => param * animationElapsedTime ** i).reduce((pre, curr) => pre + curr);
var cubicBezier = (c1, c2) => animationElapsedTime => {
var params = cubicBezierFactor(c1, c2);
return evaluatePolynomial(params, animationElapsedTime);
};
var derivativeCubicBezier = (c1, c2) => animationElapsedTime => {
var params = cubicBezierFactor(c1, c2);
var newParams = [...params.map((param, i) => param * i).slice(1), 0];
return evaluatePolynomial(newParams, animationElapsedTime);
};
var parseCubicBezier = easing => {
var _easingParts$;
var easingParts = easing.split('(');
if (easingParts.length !== 2 || easingParts[0] !== 'cubic-bezier') {
return null;
}
var numbers = (_easingParts$ = easingParts[1]) === null || _easingParts$ === void 0 || (_easingParts$ = _easingParts$.split(')')[0]) === null || _easingParts$ === void 0 ? void 0 : _easingParts$.split(',');
if (numbers == null || numbers.length !== 4) {
return null;
}
var coords = numbers.map(x => parseFloat(x));
return [coords[0], coords[1], coords[2], coords[3]];
};
var getBezierCoordinates = function getBezierCoordinates() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
if (args.length === 1) {
switch (args[0]) {
case 'linear':
return [0.0, 0.0, 1.0, 1.0];
case 'ease':
return [0.25, 0.1, 0.25, 1.0];
case 'ease-in':
return [0.42, 0.0, 1.0, 1.0];
case 'ease-out':
return [0.42, 0.0, 0.58, 1.0];
case 'ease-in-out':
return [0.0, 0.0, 0.58, 1.0];
default:
{
var easing = parseCubicBezier(args[0]);
if (easing) {
return easing;
}
}
}
}
if (args.length === 4) {
return args;
}
// Fallback for invalid inputs. The previous implementation was buggy and would lead to NaN.
// Returning linear easing is a safe default.
return [0.0, 0.0, 1.0, 1.0];
};
var createBezierEasing = (x1, y1, x2, y2) => {
var curveX = cubicBezier(x1, x2);
var curveY = cubicBezier(y1, y2);
var derCurveX = derivativeCubicBezier(x1, x2);
var rangeValue = value => {
if (value > 1) {
return 1;
}
if (value < 0) {
return 0;
}
return value;
};
var bezier = _animationElapsedTime => {
var animationElapsedTime = _animationElapsedTime > 1 ? 1 : _animationElapsedTime;
var x = animationElapsedTime;
for (var i = 0; i < 8; ++i) {
var evalT = curveX(x) - animationElapsedTime;
var derVal = derCurveX(x);
if (Math.abs(evalT - animationElapsedTime) < ACCURACY || derVal < ACCURACY) {
return curveY(x);
}
x = rangeValue(x - evalT / derVal);
}
return curveY(x);
};
bezier.isStepper = false;
return bezier;
};
// calculate cubic-bezier using Newton's method
var configBezier = exports.configBezier = function configBezier() {
return createBezierEasing(...getBezierCoordinates(...arguments));
};
/**
* Creates a performance-optimized, progress-based spring easing function.
* It pre-calculates ("bakes") spring physics frames upfront based on a fixed duration,
* then returns a pure, lightweight function mapping progress (0 to 1) to the animated position.
* This approach is ideal for low-power devices because it removes heavy physics math from the frame loop.
*/
var createSpringEasing = exports.createSpringEasing = function createSpringEasing() {
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _config$stiff = config.stiff,
stiff = _config$stiff === void 0 ? 100 : _config$stiff,
_config$damping = config.damping,
damping = _config$damping === void 0 ? 8 : _config$damping,
_config$dt = config.dt,
dt = _config$dt === void 0 ? 16.67 : _config$dt;
var destX = 1;
var positions = [0];
var currX = 0;
var currV = 0;
// Safety valve to prevent accidental infinite loops if physics config is extreme
var maxIterations = 10000;
var iterations = 0;
// 1. Run the simulation until the spring completely stops moving
while (iterations < maxIterations) {
var FSpring = -(currX - destX) * stiff;
var FDamping = currV * damping;
currV += (FSpring - FDamping) * dt / 1000;
currX += currV * dt / 1000;
positions.push(currX);
// Stop only when position is essentially at 1.0 AND bounce velocity has died down
if (Math.abs(currX - destX) < ACCURACY && Math.abs(currV) < ACCURACY) {
break;
}
iterations++;
}
// Force the absolute final element to be exactly 1.0 for a perfect finish
positions[positions.length - 1] = destX;
var maxIndex = positions.length - 1;
// 2. The ultra-smooth runtime function mapping your 0..1 progress
return t => {
var _positions$index, _positions, _positions$index2;
if (t <= 0) return 0;
if (t >= 1) return destX;
// Scale t (0..1) proportionally across our entire pre-calculated array
var exactFrame = t * maxIndex;
var index = Math.floor(exactFrame);
var fraction = exactFrame - index;
// Blend between the two closest frames
return ((_positions$index = positions[index]) !== null && _positions$index !== void 0 ? _positions$index : 0) + (((_positions = positions[index + 1]) !== null && _positions !== void 0 ? _positions : 0) - ((_positions$index2 = positions[index]) !== null && _positions$index2 !== void 0 ? _positions$index2 : 0)) * fraction;
};
};
/**
* @inline
*/
var createEasingFunction = easing => {
if (typeof easing === 'string') {
switch (easing) {
case 'ease':
case 'ease-in-out':
case 'ease-out':
case 'ease-in':
case 'linear':
return configBezier(easing);
case 'spring':
return createSpringEasing();
default:
if (easing.split('(')[0] === 'cubic-bezier') {
return configBezier(easing);
}
}
}
if (typeof easing === 'function') {
return easing;
}
return null;
};
exports.createEasingFunction = createEasingFunction;

228
frontend/node_modules/recharts/lib/animation/matchBy.js generated vendored Normal file
View file

@ -0,0 +1,228 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.matchAnimationItems = matchAnimationItems;
exports.matchAppend = void 0;
exports.matchByDataKey = matchByDataKey;
exports.matchByIndex = void 0;
var _ChartUtils = require("../util/ChartUtils");
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
/**
* A tagged union describing the status of an item during animation.
*
* - `matched`: item exists in both previous and next data interpolate between positions
* - `added`: item is new (no previous position) animate in
* - `removed`: item was in previous data but not in next animate out
*
* @since 3.9
* @see {@link https://recharts.github.io/en-US/guide/animations Animation guide}
*/
/**
* A function that extracts a key from an animation item for matching purposes.
* Items in the previous and next arrays that return the same key are considered
* the same logical item and will animate between their positions.
*
* @param item The chart item (e.g., a bar rectangle, a line point, a pie sector)
* @param index The index of the item in the array
* @returns A string or number key, or null if the item cannot be matched
*
* @since 3.9
* @see {@link https://recharts.github.io/en-US/guide/animations Animation guide}
*/
/**
* The union of all accepted `animationMatchBy` prop values:
* a built-in sentinel string, or a custom matching function.
*
* @since 3.9
* @see {@link https://recharts.github.io/en-US/guide/animations Animation guide}
*/
/**
* Match animation items by their array index (the default behavior).
*
* Previous items are paired with next items based on their position
* in the array, with proportional stretching when array lengths differ.
* When going from 5 to 15 items, each old point "covers" approximately 3 new points;
* when shrinking, some old points are skipped.
*
* @example
* import { matchByIndex } from 'recharts';
* <Line animationMatchBy={matchByIndex} />
*
* @since 3.9
* @see {@link https://recharts.github.io/en-US/guide/animations Animation guide}
*/
var matchByIndex = exports.matchByIndex = 'index';
/**
* Match animation items sequentially: previous item 0 pairs with next item 0,
* previous item 1 pairs with next item 1, and so on. When the new array is longer,
* the extra items have no match and animate in from their default position.
* When the new array is shorter, the ancient items are simply dropped.
*
* This is useful when new data is appended at the end of the array, and you want
* existing points to stay in place while new points animate in.
*
* @example
* import { matchAppend } from 'recharts';
* <Line animationMatchBy={matchAppend} />
*
* @since 3.9
* @see {@link https://recharts.github.io/en-US/guide/animations Animation guide}
*/
var matchAppend = exports.matchAppend = 'append';
/**
* Create a matching function that pairs items by a data key from their payload.
*
* Useful for time-series or streaming charts where new data points are added
* to one end and old points are removed from the other. This ensures existing
* points animate smoothly to their new positions instead of shifting by index.
*
* @param dataKey The key to look up in each item's payload (e.g., 'timestamp', 'date', 'id')
* @returns An AnimationMatchBy function that can be passed to the animationMatchBy prop
*
* @example
* import { matchByDataKey } from 'recharts';
* <Line animationMatchBy={matchByDataKey('timestamp')} />
* <Bar animationMatchBy={matchByDataKey('name')} />
* <Pie animationMatchBy={matchByDataKey('id')} />
*
* @since 3.9
* @see {@link https://recharts.github.io/en-US/guide/animations Animation guide}
*/
function matchByDataKey(dataKey) {
return item => {
if (item.payload == null || typeof item.payload !== 'object') return null;
var value = (0, _ChartUtils.getValueByDataKey)(item.payload, dataKey);
if (value == null) return null;
if (typeof value === 'string' || typeof value === 'number') return value;
return JSON.stringify(value);
};
}
function tagAlignedItems(alignedPrevItems, nextItems) {
var removedPrevItems = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var tagged = [];
/*
* We put removed points at the start because we assume that a typical chart animates right-to-left
* and the removed points will disappear from the left edge and outside the plot area.
* If you chart behaves differently you may want to customize your matching function.
*/
for (var prev of removedPrevItems) {
tagged.push({
status: 'removed',
prev
});
}
for (var i = 0; i < nextItems.length; i++) {
// This function intentionally pairs by array index. The strategy-specific functions above are
// responsible for producing an alignedPrevItems array whose indices already correspond to nextItems.
var _prev = alignedPrevItems[i];
var next = nextItems[i];
if (_prev != null) {
tagged.push({
status: 'matched',
prev: _prev,
next
});
} else {
tagged.push({
status: 'added',
next
});
}
}
return tagged;
}
function matchByIndexImpl(prevItems, nextItems) {
var factor = prevItems.length / nextItems.length;
var alignedPrevItems = nextItems.map((_, i) => prevItems[Math.floor(i * factor)]);
return tagAlignedItems(alignedPrevItems, nextItems);
}
function matchAppendImpl(prevItems, nextItems) {
var alignedPrevItems = nextItems.map((_, i) => prevItems[i]);
return tagAlignedItems(alignedPrevItems, nextItems);
}
function buildPrevKeyMap(prevItems, matchBy) {
var prevMap = new Map();
for (var i = 0; i < prevItems.length; i++) {
var _item = prevItems[i];
if (_item == null) continue;
var key = matchBy(_item, i);
if (key != null && !prevMap.has(key)) {
prevMap.set(key, _item);
}
}
return prevMap;
}
/**
* Match previous items to next items by key, and include removed items explicitly.
*
* @internal
*/
function matchByKey(prevItems, nextItems, matchBy) {
var prevMap = buildPrevKeyMap(prevItems, matchBy);
// Track which prev keys were matched
var matchedKeys = new Set();
var alignedPrevItems = nextItems.map((next, i) => {
var key = matchBy(next, i);
if (key != null) {
var prev = prevMap.get(key);
if (prev !== undefined) {
matchedKeys.add(key);
return prev;
}
}
return undefined;
});
// Removed = prev items whose keys were not matched to any next item
var removedPrevItems = [];
for (var _ref3 of prevMap) {
var _ref2 = _slicedToArray(_ref3, 2);
var key = _ref2[0];
var _item2 = _ref2[1];
if (!matchedKeys.has(key)) {
removedPrevItems.push(_item2);
}
}
return tagAlignedItems(alignedPrevItems, nextItems, removedPrevItems);
}
/**
* Match previous items to next items using the given matching strategy and return tagged animation items.
*
* On first render, all next items are returned as `{ status: 'added' }`.
* For key-based matching, unmatched previous items are appended as `{ status: 'removed' }`.
*
* @internal
*/
function matchAnimationItems(prevItems, nextItems, matchBy) {
if (nextItems == null) {
return null;
}
if (prevItems == null) {
return nextItems.map(next => ({
status: 'added',
next
}));
}
if (matchBy === matchByIndex) {
return matchByIndexImpl(prevItems, nextItems);
}
if (matchBy === matchAppend) {
return matchAppendImpl(prevItems, nextItems);
}
return matchByKey(prevItems, nextItems, matchBy);
}

View file

@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.RequestAnimationFrameTimeoutController = void 0;
/**
* Callback type for the timeout function.
* Receives current time as an argument.
*/
/**
* A function that, when called, cancels the timeout.
*
* @since 3.9
*/
/**
* TimeoutController is responsible for controlling the movement of time.
* Think of it as a clock.
*
* Recharts default implementation uses requestAnimationFrame which works great in a browser.
* You may choose to override this which is especially useful if you want to control animations.
*
* Why would you want to do this?
* - unit tests
* - animations based on something other than time: UI controls, page scroll, mouse movement ...
*
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animation guide}
*
* @since 3.9
*/
class RequestAnimationFrameTimeoutController {
setTimeout(callback) {
var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var startTime = performance.now();
var requestId = null;
var executeCallback = now => {
if (now - startTime >= delay) {
callback(now);
} else {
requestId = requestAnimationFrame(executeCallback);
}
};
requestId = requestAnimationFrame(executeCallback);
return () => {
if (requestId != null) {
cancelAnimationFrame(requestId);
}
};
}
}
exports.RequestAnimationFrameTimeoutController = RequestAnimationFrameTimeoutController;

View file

@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.AnimationControllerProvider = void 0;
exports.useAnimationController = useAnimationController;
var _react = require("react");
var _AnimationControllerImpl = require("./AnimationControllerImpl");
var AnimationControllerContext = /*#__PURE__*/(0, _react.createContext)(_AnimationControllerImpl.animationControllerImpl);
/**
* Allows overriding the default AnimationController that Recharts uses internally to drive animations.
* The default one uses requestAnimationFrame-based TimeoutController, and ticks through the animations
* as time moves forward.
*
* Why would you want to use this? Several reasons:
* - Unit tests are an excellent use (Recharts itself has ton of tests with mock TimeoutController)
* - If you want to animate charts back and forth (Recharts only animates forward)
* - If you want to replace requestAnimationFrame with something else
* - Perhaps a manual animation controls (https://recharts.github.io does this)
* - If you want to maybe animate charts based on mouse movement, or page scroll position, instead of time
*
* If you don't use this provider then all charts use the default requestAnimationFrame and default animation logic.
*
* If you use this component then all charts inside use your custom animationController.
*
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animation guide}
*
* @since 3.9
*/
var AnimationControllerProvider = exports.AnimationControllerProvider = AnimationControllerContext.Provider;
function useAnimationController(animationControllerFromProps) {
var animationControllerFromContext = (0, _react.useContext)(AnimationControllerContext);
return (0, _react.useMemo)(() => animationControllerFromProps !== null && animationControllerFromProps !== void 0 ? animationControllerFromProps : animationControllerFromContext, [animationControllerFromProps, animationControllerFromContext]);
}

View file

@ -0,0 +1,96 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useAnimationStartSnapshot = useAnimationStartSnapshot;
var _react = require("react");
/**
* Small state machine shared by animated components that need interruption-safe
* animations.
*
* Why this exists:
* Recharts stores the latest visible animation frame in mutable refs so the next
* animation can resume from that exact geometry. That works well, but there is a
* subtle trap: when an animation is interrupted, React may render several times
* before the new animation has actually emitted its own `animationElapsedTime=0` frame. If we keep
* reading and writing the same live ref during that window, the "start" value of
* the new animation can drift, which produces visible jumps.
*
* This hook separates those two responsibilities:
* - `startValue` is a frozen snapshot of the previous animation state, captured
* once per animation cycle and kept stable while that cycle is being matched
* and interpolated.
* - `previousValueRef.current` remains the mutable "latest visible frame" store
* that future animations can resume from.
*
* The hook does not know anything about points, baselines, sectors, or shapes.
* It only manages *when* a snapshot is captured and *when* new frames are allowed
* to overwrite the mutable ref.
*
* Lifecycle:
* 1. When `animationInput` changes by reference, a new cycle begins. We capture
* the current ref value into `startValue` and temporarily block writes.
* 2. When the new animation renders `animationElapsedTime=0`, we unlock writes. This ensures the new
* animation has had a chance to render its true starting frame before any live
* ref gets updated.
* 3. For `animationElapsedTime > 0`, callers may commit the visible frame back into the mutable ref.
* Callers can still veto that with `canCommit=false` (for example when a Line
* needs to wait until SVG path length has been measured).
* 4. At `animationElapsedTime=1`, we also refresh the frozen snapshot so subsequent rerenders in the
* completed state observe the finished geometry.
*/
function useAnimationStartSnapshot(animationInput, previousValueRef) {
/*
* Stores the identity of the animation cycle we are currently serving.
* As soon as this changes, we know we need a brand new frozen snapshot.
*/
var previousAnimationInputRef = (0, _react.useRef)(animationInput);
/*
* Frozen start-of-cycle value used for interpolation.
* This is the value callers should match against for the whole duration of the
* current animation, even if the live ref is updated many times afterward.
*/
var startValueRef = (0, _react.useRef)(previousValueRef.current);
/*
* Prevents us from writing back into the live ref until the new animation has
* actually rendered its own animationElapsedTime=0 frame. This avoids "pre-start" renders from
* accidentally rebasing the next animation onto already-shifted geometry.
*/
var isReadyToCommitRef = (0, _react.useRef)(true);
if (previousAnimationInputRef.current !== animationInput) {
// New animation cycle: capture exactly one frozen starting snapshot.
previousAnimationInputRef.current = animationInput;
startValueRef.current = previousValueRef.current;
// Writes stay blocked until the new cycle acknowledges its animationElapsedTime=0 frame.
isReadyToCommitRef.current = false;
}
var syncStepValue = (0, _react.useCallback)(function (stepValue, animationElapsedTime) {
var canCommit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
if (animationElapsedTime === 0) {
/*
* animationElapsedTime=0 is the handshake that says: "the new animation has now rendered its
* own starting frame". We do not write anything yet; we only allow later
* in-flight frames to be committed safely.
*/
isReadyToCommitRef.current = true;
return;
}
if (animationElapsedTime === 1) {
// Keep the frozen snapshot aligned with the fully completed geometry.
startValueRef.current = stepValue;
}
if (animationElapsedTime > 0 && isReadyToCommitRef.current && canCommit) {
/*
* Commit the latest visible frame so a future interruption can resume from
* exactly what the user saw on screen most recently.
*/
// eslint-disable-next-line no-param-reassign
previousValueRef.current = stepValue;
}
}, [previousValueRef]);
return {
startValue: startValueRef.current,
syncStepValue
};
}

14
frontend/node_modules/recharts/lib/animation/util.js generated vendored Normal file
View file

@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getTransitionVal = exports.getDashCase = void 0;
/*
* @description: convert camel case to dash case
* string => string
*/
var getDashCase = name => name.replace(/([A-Z])/g, v => "-".concat(v.toLowerCase()));
exports.getDashCase = getDashCase;
var getTransitionVal = (props, duration, easing) => props.map(prop => "".concat(getDashCase(prop), " ").concat(duration, "ms ").concat(easing)).join(',');
exports.getTransitionVal = getTransitionVal;