@railtownai/railtracks-visualizer 0.0.54 → 0.0.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -8,7 +8,7 @@ import RcDrawer from '@rc-component/drawer';
8
8
  import useId$2 from '@rc-component/util/es/hooks/useId';
9
9
  import { composeRef, supportRef, getNodeRef, supportNodeRef, useComposeRef as useComposeRef$1 } from '@rc-component/util/es/ref';
10
10
  import '@rc-component/form';
11
- import { warning as warning$1, merge, useEvent, toArray as toArray$1, omit, useComposeRef, useControlledState } from '@rc-component/util';
11
+ import { warning as warning$2, merge, useEvent, toArray as toArray$1, omit, useComposeRef, useControlledState } from '@rc-component/util';
12
12
  import CloseOutlined from '@ant-design/icons/es/icons/CloseOutlined';
13
13
  import pickAttrs from '@rc-component/util/es/pickAttrs';
14
14
  import Pagination$1 from '@rc-component/pagination/es/locale/en_US';
@@ -8051,7 +8051,7 @@ function fixedForwardRef(render) {
8051
8051
  return forwardRef(render);
8052
8052
  }
8053
8053
  // we need this hook to prevent a warning when using react-flow in SSR
8054
- const useIsomorphicLayoutEffect$2 = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
8054
+ const useIsomorphicLayoutEffect$3 = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
8055
8055
  /**
8056
8056
  * This hook returns a queue that can be used to batch updates.
8057
8057
  *
@@ -8076,7 +8076,7 @@ const useIsomorphicLayoutEffect$2 = typeof window !== 'undefined' ? useLayoutEff
8076
8076
  * Layout effects are guaranteed to run before the next render which means we
8077
8077
  * shouldn't run into any issues with stale state or weird issues that come from
8078
8078
  * rendering things one frame later than expected (we used to use `setTimeout`).
8079
- */ useIsomorphicLayoutEffect$2(()=>{
8079
+ */ useIsomorphicLayoutEffect$3(()=>{
8080
8080
  const queueItems = queue.get();
8081
8081
  if (queueItems.length) {
8082
8082
  runQueue(queueItems);
@@ -15204,7 +15204,7 @@ function requireHoistNonReactStatics_cjs() {
15204
15204
 
15205
15205
  requireHoistNonReactStatics_cjs();
15206
15206
 
15207
- var isBrowser = true;
15207
+ var isBrowser$1 = true;
15208
15208
  function getRegisteredStyles(registered, registeredStyles, classNames) {
15209
15209
  var rawClassName = '';
15210
15210
  classNames.split(' ').forEach(function(className) {
@@ -15226,7 +15226,7 @@ var registerStyles = function registerStyles(cache, serialized, isStringTag) {
15226
15226
  // in node since emotion-server relies on whether a style is in
15227
15227
  // the registered cache to know whether a style is global or not
15228
15228
  // also, note that this check will be dead code eliminated in the browser
15229
- isBrowser === false) && cache.registered[className] === undefined) {
15229
+ isBrowser$1 === false) && cache.registered[className] === undefined) {
15230
15230
  cache.registered[className] = serialized.styles;
15231
15231
  }
15232
15232
  };
@@ -15874,6 +15874,21 @@ const ThemeProvider = ({ children, theme: propTheme })=>{
15874
15874
  }, [
15875
15875
  propTheme
15876
15876
  ]);
15877
+ // Sync html.dark class for GlobalStyles and other CSS that uses html.dark
15878
+ useEffect(()=>{
15879
+ const isDark = currentTheme === darkTheme;
15880
+ try {
15881
+ if (isDark) {
15882
+ document.documentElement.classList.add("dark");
15883
+ } else {
15884
+ document.documentElement.classList.remove("dark");
15885
+ }
15886
+ } catch (e) {
15887
+ // document might not be available (e.g. SSR)
15888
+ }
15889
+ }, [
15890
+ currentTheme
15891
+ ]);
15877
15892
  // Only listen for storage events if no theme prop is provided
15878
15893
  useEffect(()=>{
15879
15894
  if (propTheme) {
@@ -20981,7 +20996,7 @@ function cn(...inputs) {
20981
20996
  /**
20982
20997
  * Formats a metric value for display based on evaluator metric definitions.
20983
20998
  * Handles Categorical (index → option label), Continuous (decimal), and fallback.
20984
- */ function formatMetricValue(evaluator, metricName, value) {
20999
+ */ function formatMetricValue$1(evaluator, metricName, value) {
20985
21000
  if (value === undefined || value === null) return "-";
20986
21001
  const numericValue = typeof value === "number" ? value : Number(value);
20987
21002
  if (isNaN(numericValue)) return "-";
@@ -21608,7 +21623,7 @@ const Badge = ({ variant = "default", children, title, placement = "top" })=>{
21608
21623
  };
21609
21624
 
21610
21625
  function noop$2() {}
21611
- const { resetWarned: rcResetWarned } = warning$1;
21626
+ const { resetWarned: rcResetWarned } = warning$2;
21612
21627
  let deprecatedWarnList = null;
21613
21628
  function resetWarned() {
21614
21629
  deprecatedWarnList = null;
@@ -21617,14 +21632,14 @@ function resetWarned() {
21617
21632
  let _warning = noop$2;
21618
21633
  if (process.env.NODE_ENV !== 'production') {
21619
21634
  _warning = (valid, component, message)=>{
21620
- warning$1(valid, `[antd: ${component}] ${message}`);
21635
+ warning$2(valid, `[antd: ${component}] ${message}`);
21621
21636
  // StrictMode will inject console which will not throw warning in React 17.
21622
21637
  if (process.env.NODE_ENV === 'test') {
21623
21638
  resetWarned();
21624
21639
  }
21625
21640
  };
21626
21641
  }
21627
- const warning = _warning;
21642
+ const warning$1 = _warning;
21628
21643
  const WarningContext = /*#__PURE__*/ React.createContext({});
21629
21644
  /**
21630
21645
  * This is a hook but we not named as `useWarning`
@@ -21648,7 +21663,7 @@ const WarningContext = /*#__PURE__*/ React.createContext({});
21648
21663
  console.warn('[antd] There exists deprecated usage in your code:', deprecatedWarnList);
21649
21664
  }
21650
21665
  } else {
21651
- process.env.NODE_ENV !== "production" ? warning(valid, component, message) : void 0;
21666
+ process.env.NODE_ENV !== "production" ? warning$1(valid, component, message) : void 0;
21652
21667
  }
21653
21668
  }
21654
21669
  };
@@ -23499,6 +23514,367 @@ const useZIndex = (componentType, customZIndex)=>{
23499
23514
  return result;
23500
23515
  };
23501
23516
 
23517
+ const genAlertTypeStyle = (bgColor, borderColor, iconColor, token, alertCls)=>({
23518
+ background: bgColor,
23519
+ border: `${unit(token.lineWidth)} ${token.lineType} ${borderColor}`,
23520
+ [`${alertCls}-icon`]: {
23521
+ color: iconColor
23522
+ }
23523
+ });
23524
+ const genBaseStyle$6 = (token)=>{
23525
+ const { componentCls, motionDurationSlow: duration, marginXS, marginSM, fontSize, fontSizeLG, lineHeight, borderRadiusLG: borderRadius, motionEaseInOutCirc, withDescriptionIconSize, colorText, colorTextHeading, withDescriptionPadding, defaultPadding } = token;
23526
+ return {
23527
+ [componentCls]: {
23528
+ ...resetComponent(token),
23529
+ position: 'relative',
23530
+ display: 'flex',
23531
+ alignItems: 'center',
23532
+ padding: defaultPadding,
23533
+ wordWrap: 'break-word',
23534
+ borderRadius,
23535
+ [`&${componentCls}-rtl`]: {
23536
+ direction: 'rtl'
23537
+ },
23538
+ [`${componentCls}-section`]: {
23539
+ flex: 1,
23540
+ minWidth: 0
23541
+ },
23542
+ [`${componentCls}-icon`]: {
23543
+ marginInlineEnd: marginXS,
23544
+ lineHeight: 0
23545
+ },
23546
+ '&-description': {
23547
+ display: 'none',
23548
+ fontSize,
23549
+ lineHeight
23550
+ },
23551
+ '&-title': {
23552
+ color: colorTextHeading
23553
+ },
23554
+ [`&${componentCls}-motion-leave`]: {
23555
+ overflow: 'hidden',
23556
+ opacity: 1,
23557
+ transition: [
23558
+ `max-height`,
23559
+ `opacity`,
23560
+ `padding-top`,
23561
+ `padding-bottom`,
23562
+ `margin-bottom`
23563
+ ].map((prop)=>`${prop} ${duration} ${motionEaseInOutCirc}`).join(', ')
23564
+ },
23565
+ [`&${componentCls}-motion-leave-active`]: {
23566
+ maxHeight: 0,
23567
+ marginBottom: '0 !important',
23568
+ paddingTop: 0,
23569
+ paddingBottom: 0,
23570
+ opacity: 0
23571
+ }
23572
+ },
23573
+ [`${componentCls}-with-description`]: {
23574
+ alignItems: 'flex-start',
23575
+ padding: withDescriptionPadding,
23576
+ [`${componentCls}-icon`]: {
23577
+ marginInlineEnd: marginSM,
23578
+ fontSize: withDescriptionIconSize,
23579
+ lineHeight: 0
23580
+ },
23581
+ [`${componentCls}-title`]: {
23582
+ display: 'block',
23583
+ marginBottom: marginXS,
23584
+ color: colorTextHeading,
23585
+ fontSize: fontSizeLG
23586
+ },
23587
+ [`${componentCls}-description`]: {
23588
+ display: 'block',
23589
+ color: colorText
23590
+ }
23591
+ },
23592
+ [`${componentCls}-banner`]: {
23593
+ marginBottom: 0,
23594
+ border: '0 !important',
23595
+ borderRadius: 0
23596
+ }
23597
+ };
23598
+ };
23599
+ const genTypeStyle = (token)=>{
23600
+ const { componentCls, colorSuccess, colorSuccessBorder, colorSuccessBg, colorWarning, colorWarningBorder, colorWarningBg, colorError, colorErrorBorder, colorErrorBg, colorInfo, colorInfoBorder, colorInfoBg } = token;
23601
+ return {
23602
+ [componentCls]: {
23603
+ '&-success': genAlertTypeStyle(colorSuccessBg, colorSuccessBorder, colorSuccess, token, componentCls),
23604
+ '&-info': genAlertTypeStyle(colorInfoBg, colorInfoBorder, colorInfo, token, componentCls),
23605
+ '&-warning': genAlertTypeStyle(colorWarningBg, colorWarningBorder, colorWarning, token, componentCls),
23606
+ '&-error': {
23607
+ ...genAlertTypeStyle(colorErrorBg, colorErrorBorder, colorError, token, componentCls),
23608
+ [`${componentCls}-description > pre`]: {
23609
+ margin: 0,
23610
+ padding: 0
23611
+ }
23612
+ }
23613
+ }
23614
+ };
23615
+ };
23616
+ const genActionStyle = (token)=>{
23617
+ const { componentCls, iconCls, motionDurationMid, marginXS, fontSizeIcon, colorIcon, colorIconHover } = token;
23618
+ return {
23619
+ [componentCls]: {
23620
+ '&-actions': {
23621
+ marginInlineStart: marginXS
23622
+ },
23623
+ [`${componentCls}-close-icon`]: {
23624
+ marginInlineStart: marginXS,
23625
+ padding: 0,
23626
+ overflow: 'hidden',
23627
+ fontSize: fontSizeIcon,
23628
+ lineHeight: unit(fontSizeIcon),
23629
+ backgroundColor: 'transparent',
23630
+ border: 'none',
23631
+ outline: 'none',
23632
+ cursor: 'pointer',
23633
+ [`${iconCls}-close`]: {
23634
+ color: colorIcon,
23635
+ transition: `color ${motionDurationMid}`,
23636
+ '&:hover': {
23637
+ color: colorIconHover
23638
+ }
23639
+ }
23640
+ },
23641
+ '&-close-text': {
23642
+ color: colorIcon,
23643
+ transition: `color ${motionDurationMid}`,
23644
+ '&:hover': {
23645
+ color: colorIconHover
23646
+ }
23647
+ }
23648
+ }
23649
+ };
23650
+ };
23651
+ const prepareComponentToken$n = (token)=>{
23652
+ const paddingHorizontal = 12; // Fixed value here.
23653
+ return {
23654
+ withDescriptionIconSize: token.fontSizeHeading3,
23655
+ defaultPadding: `${token.paddingContentVerticalSM}px ${paddingHorizontal}px`,
23656
+ withDescriptionPadding: `${token.paddingMD}px ${token.paddingContentHorizontalLG}px`
23657
+ };
23658
+ };
23659
+ var useStyle$u = genStyleHooks('Alert', (token)=>[
23660
+ genBaseStyle$6(token),
23661
+ genTypeStyle(token),
23662
+ genActionStyle(token)
23663
+ ], prepareComponentToken$n);
23664
+
23665
+ const IconNode = (props)=>{
23666
+ const { icon, type, className, style, successIcon, infoIcon, warningIcon, errorIcon } = props;
23667
+ const iconMapFilled = {
23668
+ success: successIcon ?? /*#__PURE__*/ React.createElement(CheckCircleFilled, null),
23669
+ info: infoIcon ?? /*#__PURE__*/ React.createElement(InfoCircleFilled, null),
23670
+ error: errorIcon ?? /*#__PURE__*/ React.createElement(CloseCircleFilled, null),
23671
+ warning: warningIcon ?? /*#__PURE__*/ React.createElement(ExclamationCircleFilled, null)
23672
+ };
23673
+ return /*#__PURE__*/ React.createElement("span", {
23674
+ className: className,
23675
+ style: style
23676
+ }, icon ?? iconMapFilled[type]);
23677
+ };
23678
+ const CloseIconNode = (props)=>{
23679
+ const { isClosable, prefixCls, closeIcon, handleClose, ariaProps, className, style } = props;
23680
+ const mergedCloseIcon = closeIcon === true || closeIcon === undefined ? /*#__PURE__*/ React.createElement(CloseOutlined, null) : closeIcon;
23681
+ return isClosable ? /*#__PURE__*/ React.createElement("button", {
23682
+ type: "button",
23683
+ onClick: handleClose,
23684
+ className: clsx(`${prefixCls}-close-icon`, className),
23685
+ tabIndex: 0,
23686
+ style: style,
23687
+ ...ariaProps
23688
+ }, mergedCloseIcon) : null;
23689
+ };
23690
+ const Alert$1 = /*#__PURE__*/ React.forwardRef((props, ref)=>{
23691
+ const { description, prefixCls: customizePrefixCls, message, title, banner, className, rootClassName, style, onMouseEnter, onMouseLeave, onClick, afterClose, showIcon, closable, closeText, closeIcon, action, id, styles, classNames, ...otherProps } = props;
23692
+ const mergedTitle = title ?? message;
23693
+ const [closed, setClosed] = React.useState(false);
23694
+ if (process.env.NODE_ENV !== 'production') {
23695
+ const warning = devUseWarning('Alert');
23696
+ [
23697
+ [
23698
+ 'closeText',
23699
+ 'closable.closeIcon'
23700
+ ],
23701
+ [
23702
+ 'message',
23703
+ 'title'
23704
+ ]
23705
+ ].forEach(([deprecatedName, newName])=>{
23706
+ warning.deprecated(!(deprecatedName in props), deprecatedName, newName);
23707
+ });
23708
+ }
23709
+ const internalRef = React.useRef(null);
23710
+ React.useImperativeHandle(ref, ()=>({
23711
+ nativeElement: internalRef.current
23712
+ }));
23713
+ const { getPrefixCls, direction, closable: contextClosable, closeIcon: contextCloseIcon, className: contextClassName, style: contextStyle, classNames: contextClassNames, styles: contextStyles, successIcon, infoIcon, warningIcon, errorIcon } = useComponentConfig('alert');
23714
+ const prefixCls = getPrefixCls('alert', customizePrefixCls);
23715
+ const [hashId, cssVarCls] = useStyle$u(prefixCls);
23716
+ const { onClose: closableOnClose, afterClose: closableAfterClose } = closable && typeof closable === 'object' ? closable : {};
23717
+ const handleClose = (e)=>{
23718
+ setClosed(true);
23719
+ (closableOnClose ?? props.onClose)?.(e);
23720
+ };
23721
+ const type = React.useMemo(()=>{
23722
+ if (props.type !== undefined) {
23723
+ return props.type;
23724
+ }
23725
+ // banner mode defaults to 'warning'
23726
+ return banner ? 'warning' : 'info';
23727
+ }, [
23728
+ props.type,
23729
+ banner
23730
+ ]);
23731
+ // closeable when closeText or closeIcon is assigned
23732
+ const isClosable = React.useMemo(()=>{
23733
+ if (typeof closable === 'object' && closable.closeIcon) {
23734
+ return true;
23735
+ }
23736
+ if (closeText) {
23737
+ return true;
23738
+ }
23739
+ if (typeof closable === 'boolean') {
23740
+ return closable;
23741
+ }
23742
+ // should be true when closeIcon is 0 or ''
23743
+ if (closeIcon !== false && isNonNullable(closeIcon)) {
23744
+ return true;
23745
+ }
23746
+ return !!contextClosable;
23747
+ }, [
23748
+ closeText,
23749
+ closeIcon,
23750
+ closable,
23751
+ contextClosable
23752
+ ]);
23753
+ // banner mode defaults to Icon
23754
+ const isShowIcon = banner && showIcon === undefined ? true : showIcon;
23755
+ // =========== Merged Props for Semantic ==========
23756
+ const mergedProps = {
23757
+ ...props,
23758
+ prefixCls,
23759
+ type,
23760
+ showIcon: isShowIcon,
23761
+ closable: isClosable
23762
+ };
23763
+ const [mergedClassNames, mergedStyles] = useMergeSemantic([
23764
+ contextClassNames,
23765
+ classNames
23766
+ ], [
23767
+ contextStyles,
23768
+ styles
23769
+ ], {
23770
+ props: mergedProps
23771
+ });
23772
+ const alertCls = clsx(prefixCls, `${prefixCls}-${type}`, {
23773
+ [`${prefixCls}-with-description`]: !!description,
23774
+ [`${prefixCls}-no-icon`]: !isShowIcon,
23775
+ [`${prefixCls}-banner`]: !!banner,
23776
+ [`${prefixCls}-rtl`]: direction === 'rtl'
23777
+ }, contextClassName, className, rootClassName, mergedClassNames.root, cssVarCls, hashId);
23778
+ const restProps = pickAttrs(otherProps, {
23779
+ aria: true,
23780
+ data: true
23781
+ });
23782
+ const mergedCloseIcon = React.useMemo(()=>{
23783
+ if (typeof closable === 'object' && closable.closeIcon) {
23784
+ return closable.closeIcon;
23785
+ }
23786
+ if (closeText) {
23787
+ return closeText;
23788
+ }
23789
+ if (closeIcon !== undefined) {
23790
+ return closeIcon;
23791
+ }
23792
+ if (typeof contextClosable === 'object' && contextClosable.closeIcon) {
23793
+ return contextClosable.closeIcon;
23794
+ }
23795
+ return contextCloseIcon;
23796
+ }, [
23797
+ closeIcon,
23798
+ closable,
23799
+ contextClosable,
23800
+ closeText,
23801
+ contextCloseIcon
23802
+ ]);
23803
+ const mergedAriaProps = React.useMemo(()=>{
23804
+ const merged = closable ?? contextClosable;
23805
+ if (typeof merged === 'object') {
23806
+ return pickAttrs(merged, {
23807
+ data: true,
23808
+ aria: true
23809
+ });
23810
+ }
23811
+ return {};
23812
+ }, [
23813
+ closable,
23814
+ contextClosable
23815
+ ]);
23816
+ return /*#__PURE__*/ React.createElement(CSSMotion, {
23817
+ visible: !closed,
23818
+ motionName: `${prefixCls}-motion`,
23819
+ motionAppear: false,
23820
+ motionEnter: false,
23821
+ onLeaveStart: (node)=>({
23822
+ maxHeight: node.offsetHeight
23823
+ }),
23824
+ onLeaveEnd: closableAfterClose ?? afterClose
23825
+ }, ({ className: motionClassName, style: motionStyle }, setRef)=>/*#__PURE__*/ React.createElement("div", {
23826
+ id: id,
23827
+ ref: composeRef(internalRef, setRef),
23828
+ "data-show": !closed,
23829
+ className: clsx(alertCls, motionClassName),
23830
+ style: {
23831
+ ...mergedStyles.root,
23832
+ ...contextStyle,
23833
+ ...style,
23834
+ ...motionStyle
23835
+ },
23836
+ onMouseEnter: onMouseEnter,
23837
+ onMouseLeave: onMouseLeave,
23838
+ onClick: onClick,
23839
+ role: "alert",
23840
+ ...restProps
23841
+ }, isShowIcon ? /*#__PURE__*/ React.createElement(IconNode, {
23842
+ className: clsx(`${prefixCls}-icon`, mergedClassNames.icon),
23843
+ style: mergedStyles.icon,
23844
+ description: description,
23845
+ icon: props.icon,
23846
+ prefixCls: prefixCls,
23847
+ type: type,
23848
+ successIcon: successIcon,
23849
+ infoIcon: infoIcon,
23850
+ warningIcon: warningIcon,
23851
+ errorIcon: errorIcon
23852
+ }) : null, /*#__PURE__*/ React.createElement("div", {
23853
+ className: clsx(`${prefixCls}-section`, mergedClassNames.section),
23854
+ style: mergedStyles.section
23855
+ }, mergedTitle ? /*#__PURE__*/ React.createElement("div", {
23856
+ className: clsx(`${prefixCls}-title`, mergedClassNames.title),
23857
+ style: mergedStyles.title
23858
+ }, mergedTitle) : null, description ? /*#__PURE__*/ React.createElement("div", {
23859
+ className: clsx(`${prefixCls}-description`, mergedClassNames.description),
23860
+ style: mergedStyles.description
23861
+ }, description) : null), action ? /*#__PURE__*/ React.createElement("div", {
23862
+ className: clsx(`${prefixCls}-actions`, mergedClassNames.actions),
23863
+ style: mergedStyles.actions
23864
+ }, action) : null, /*#__PURE__*/ React.createElement(CloseIconNode, {
23865
+ className: mergedClassNames.close,
23866
+ style: mergedStyles.close,
23867
+ isClosable: isClosable,
23868
+ prefixCls: prefixCls,
23869
+ closeIcon: mergedCloseIcon,
23870
+ handleClose: handleClose,
23871
+ ariaProps: mergedAriaProps
23872
+ })));
23873
+ });
23874
+ if (process.env.NODE_ENV !== 'production') {
23875
+ Alert$1.displayName = 'Alert';
23876
+ }
23877
+
23502
23878
  function _classCallCheck(a, n) {
23503
23879
  if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
23504
23880
  }
@@ -23540,6 +23916,110 @@ function _createClass(e, r, t) {
23540
23916
  }), e;
23541
23917
  }
23542
23918
 
23919
+ function _getPrototypeOf(t) {
23920
+ return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(t) {
23921
+ return t.__proto__ || Object.getPrototypeOf(t);
23922
+ }, _getPrototypeOf(t);
23923
+ }
23924
+
23925
+ function _isNativeReflectConstruct() {
23926
+ try {
23927
+ var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
23928
+ } catch (t) {}
23929
+ return (_isNativeReflectConstruct = function _isNativeReflectConstruct() {
23930
+ return !!t;
23931
+ })();
23932
+ }
23933
+
23934
+ function _assertThisInitialized(e) {
23935
+ if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
23936
+ return e;
23937
+ }
23938
+
23939
+ function _possibleConstructorReturn(t, e) {
23940
+ if (e && ("object" == _typeof(e) || "function" == typeof e)) return e;
23941
+ if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
23942
+ return _assertThisInitialized(t);
23943
+ }
23944
+
23945
+ function _callSuper(t, o, e) {
23946
+ return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
23947
+ }
23948
+
23949
+ function _setPrototypeOf(t, e) {
23950
+ return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(t, e) {
23951
+ return t.__proto__ = e, t;
23952
+ }, _setPrototypeOf(t, e);
23953
+ }
23954
+
23955
+ function _inherits(t, e) {
23956
+ if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
23957
+ t.prototype = Object.create(e && e.prototype, {
23958
+ constructor: {
23959
+ value: t,
23960
+ writable: true,
23961
+ configurable: true
23962
+ }
23963
+ }), Object.defineProperty(t, "prototype", {
23964
+ writable: false
23965
+ }), e && _setPrototypeOf(t, e);
23966
+ }
23967
+
23968
+ let ErrorBoundary$1 = /*#__PURE__*/ function(_React$Component) {
23969
+ function ErrorBoundary() {
23970
+ var _this;
23971
+ _classCallCheck(this, ErrorBoundary);
23972
+ _this = _callSuper(this, ErrorBoundary, arguments);
23973
+ _this.state = {
23974
+ error: undefined,
23975
+ info: {
23976
+ componentStack: ''
23977
+ }
23978
+ };
23979
+ return _this;
23980
+ }
23981
+ _inherits(ErrorBoundary, _React$Component);
23982
+ return _createClass(ErrorBoundary, [
23983
+ {
23984
+ key: "componentDidCatch",
23985
+ value: function componentDidCatch(error, info) {
23986
+ this.setState({
23987
+ error,
23988
+ info
23989
+ });
23990
+ }
23991
+ },
23992
+ {
23993
+ key: "render",
23994
+ value: function render() {
23995
+ const { message, title, description, id, children } = this.props;
23996
+ const { error, info } = this.state;
23997
+ const mergedTitle = title ?? message;
23998
+ const componentStack = info?.componentStack || null;
23999
+ const errorMessage = typeof mergedTitle === 'undefined' ? (error || '').toString() : mergedTitle;
24000
+ const errorDescription = typeof description === 'undefined' ? componentStack : description;
24001
+ if (error) {
24002
+ return /*#__PURE__*/ React.createElement(Alert$1, {
24003
+ id: id,
24004
+ type: "error",
24005
+ title: errorMessage,
24006
+ description: /*#__PURE__*/ React.createElement("pre", {
24007
+ style: {
24008
+ fontSize: '0.9em',
24009
+ overflowX: 'auto'
24010
+ }
24011
+ }, errorDescription)
24012
+ });
24013
+ }
24014
+ return children;
24015
+ }
24016
+ }
24017
+ ]);
24018
+ }(React.Component);
24019
+
24020
+ const Alert = Alert$1;
24021
+ Alert.ErrorBoundary = ErrorBoundary$1;
24022
+
23543
24023
  function isWindow(obj) {
23544
24024
  return isNonNullable(obj) && obj === obj.window;
23545
24025
  }
@@ -23822,7 +24302,7 @@ var PropWarning$1 = process.env.NODE_ENV !== 'production' ? PropWarning : ()=>nu
23822
24302
  * theme register info here to help developer get warning info.
23823
24303
  */ let existThemeConfig = false;
23824
24304
  const warnContext = process.env.NODE_ENV !== 'production' ? (componentName)=>{
23825
- process.env.NODE_ENV !== "production" ? warning(!existThemeConfig, componentName, `Static function can not consume context like dynamic theme. Please use 'App' component instead.`) : void 0;
24305
+ process.env.NODE_ENV !== "production" ? warning$1(!existThemeConfig, componentName, `Static function can not consume context like dynamic theme. Please use 'App' component instead.`) : void 0;
23826
24306
  } : /* istanbul ignore next */ null;
23827
24307
  // These props is used by `useContext` directly in sub component
23828
24308
  const PASSED_PROPS = [
@@ -24138,7 +24618,7 @@ ConfigProvider.config = setGlobalConfig;
24138
24618
  ConfigProvider.useConfig = useConfig;
24139
24619
  Object.defineProperty(ConfigProvider, 'SizeContext', {
24140
24620
  get: ()=>{
24141
- process.env.NODE_ENV !== "production" ? warning(false, 'ConfigProvider', 'ConfigProvider.SizeContext is deprecated. Please use `ConfigProvider.useConfig().componentSize` instead.') : void 0;
24621
+ process.env.NODE_ENV !== "production" ? warning$1(false, 'ConfigProvider', 'ConfigProvider.SizeContext is deprecated. Please use `ConfigProvider.useConfig().componentSize` instead.') : void 0;
24142
24622
  return SizeContext;
24143
24623
  }
24144
24624
  });
@@ -46790,7 +47270,7 @@ const asyncCopy = async (text, isHtmlFormat)=>{
46790
47270
  };
46791
47271
  async function copy(text, config) {
46792
47272
  if (typeof text !== 'string') {
46793
- process.env.NODE_ENV !== "production" ? warning(false, 'The clipboard content must be of string type', '') : void 0;
47273
+ process.env.NODE_ENV !== "production" ? warning$1(false, 'The clipboard content must be of string type', '') : void 0;
46794
47274
  return false;
46795
47275
  }
46796
47276
  const isHtmlFormat = config?.format === 'text/html';
@@ -47579,7 +48059,7 @@ const Base = /*#__PURE__*/ React.forwardRef((props, ref)=>{
47579
48059
  }, node) : node, renderEllipsis(canEllipsis)))))));
47580
48060
  });
47581
48061
 
47582
- const Link = /*#__PURE__*/ React.forwardRef((props, ref)=>{
48062
+ const Link$1 = /*#__PURE__*/ React.forwardRef((props, ref)=>{
47583
48063
  const { ellipsis, rel, children, // @ts-expect-error: https://github.com/ant-design/ant-design/issues/26622
47584
48064
  navigate: _navigate, ...restProps } = props;
47585
48065
  if (process.env.NODE_ENV !== 'production') {
@@ -47655,7 +48135,7 @@ const Title$1 = /*#__PURE__*/ React.forwardRef((props, ref)=>{
47655
48135
 
47656
48136
  const Typography = Typography$1;
47657
48137
  Typography.Text = Text$1;
47658
- Typography.Link = Link;
48138
+ Typography.Link = Link$1;
47659
48139
  Typography.Title = Title$1;
47660
48140
  Typography.Paragraph = Paragraph;
47661
48141
 
@@ -49639,7 +50119,7 @@ const Timeline = ({ stamps, currentStep, onStepChange, onToggle })=>{
49639
50119
  };
49640
50120
 
49641
50121
  // src/primitive.tsx
49642
- function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
50122
+ function composeEventHandlers$1(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
49643
50123
  return function handleEvent(event) {
49644
50124
  originalEventHandler?.(event);
49645
50125
  if (checkForDefaultPrevented === false || !event.defaultPrevented) {
@@ -50152,9 +50632,9 @@ var DismissableLayer = React.forwardRef((props, forwardedRef)=>{
50152
50632
  pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? "auto" : "none" : void 0,
50153
50633
  ...props.style
50154
50634
  },
50155
- onFocusCapture: composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture),
50156
- onBlurCapture: composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture),
50157
- onPointerDownCapture: composeEventHandlers(props.onPointerDownCapture, pointerDownOutside.onPointerDownCapture)
50635
+ onFocusCapture: composeEventHandlers$1(props.onFocusCapture, focusOutside.onFocusCapture),
50636
+ onBlurCapture: composeEventHandlers$1(props.onBlurCapture, focusOutside.onBlurCapture),
50637
+ onPointerDownCapture: composeEventHandlers$1(props.onPointerDownCapture, pointerDownOutside.onPointerDownCapture)
50158
50638
  });
50159
50639
  });
50160
50640
  DismissableLayer.displayName = DISMISSABLE_LAYER_NAME;
@@ -50788,7 +51268,7 @@ var noScrollbarsClassName = 'with-scroll-bars-hidden';
50788
51268
  return ref.facade;
50789
51269
  }
50790
51270
 
50791
- var useIsomorphicLayoutEffect$1 = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
51271
+ var useIsomorphicLayoutEffect$2 = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
50792
51272
  var currentValues = new WeakMap();
50793
51273
  /**
50794
51274
  * Merges two or more refs together providing a single interface to set their value
@@ -50810,7 +51290,7 @@ var currentValues = new WeakMap();
50810
51290
  });
50811
51291
  });
50812
51292
  // handle refs changes - added or removed
50813
- useIsomorphicLayoutEffect$1(function() {
51293
+ useIsomorphicLayoutEffect$2(function() {
50814
51294
  var oldValue = currentValues.get(callbackRef);
50815
51295
  if (oldValue) {
50816
51296
  var prevRefs_1 = new Set(oldValue);
@@ -51699,7 +52179,7 @@ var DialogTrigger = React.forwardRef((props, forwardedRef)=>{
51699
52179
  "data-state": getState(context.open),
51700
52180
  ...triggerProps,
51701
52181
  ref: composedTriggerRef,
51702
- onClick: composeEventHandlers(props.onClick, context.onOpenToggle)
52182
+ onClick: composeEventHandlers$1(props.onClick, context.onOpenToggle)
51703
52183
  });
51704
52184
  });
51705
52185
  DialogTrigger.displayName = TRIGGER_NAME;
@@ -51791,17 +52271,17 @@ var DialogContentModal = React.forwardRef((props, forwardedRef)=>{
51791
52271
  ref: composedRefs,
51792
52272
  trapFocus: context.open,
51793
52273
  disableOutsidePointerEvents: true,
51794
- onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event)=>{
52274
+ onCloseAutoFocus: composeEventHandlers$1(props.onCloseAutoFocus, (event)=>{
51795
52275
  event.preventDefault();
51796
52276
  context.triggerRef.current?.focus();
51797
52277
  }),
51798
- onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event)=>{
52278
+ onPointerDownOutside: composeEventHandlers$1(props.onPointerDownOutside, (event)=>{
51799
52279
  const originalEvent = event.detail.originalEvent;
51800
52280
  const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
51801
52281
  const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
51802
52282
  if (isRightClick) event.preventDefault();
51803
52283
  }),
51804
- onFocusOutside: composeEventHandlers(props.onFocusOutside, (event)=>event.preventDefault())
52284
+ onFocusOutside: composeEventHandlers$1(props.onFocusOutside, (event)=>event.preventDefault())
51805
52285
  });
51806
52286
  });
51807
52287
  var DialogContentNonModal = React.forwardRef((props, forwardedRef)=>{
@@ -51908,7 +52388,7 @@ var DialogClose = React.forwardRef((props, forwardedRef)=>{
51908
52388
  type: "button",
51909
52389
  ...closeProps,
51910
52390
  ref: forwardedRef,
51911
- onClick: composeEventHandlers(props.onClick, ()=>context.onOpenChange(false))
52391
+ onClick: composeEventHandlers$1(props.onClick, ()=>context.onOpenChange(false))
51912
52392
  });
51913
52393
  });
51914
52394
  DialogClose.displayName = CLOSE_NAME;
@@ -113501,6 +113981,12 @@ function dtoMetricToMetric(def) {
113501
113981
  if (idx !== undefined && idx >= 0) {
113502
113982
  aggregatedResults[evaluatorId][item.metric.name] = idx;
113503
113983
  }
113984
+ } else if ((isLLMResult(item) || isToolResult(item)) && "result_name" in item && typeof item.value === "number") {
113985
+ // Raw LLM/Tool results: aggregate by result_name (metric name) for comparison view
113986
+ const name = item.result_name;
113987
+ const arr = valuesByMetric.get(name) ?? [];
113988
+ arr.push(item.value);
113989
+ valuesByMetric.set(name, arr);
113504
113990
  }
113505
113991
  }
113506
113992
  // Compute mean across all values for each metric
@@ -113552,117 +114038,114 @@ function dtoMetricToMetric(def) {
113552
114038
  return "evaluator_results" in x && Array.isArray(x.evaluator_results);
113553
114039
  }
113554
114040
 
113555
- const EvaluationsCompare = ({ open, onClose, sourceEvaluationId, targetEvaluationId, evaluations, onSourceChange, onTargetChange })=>{
113556
- const { isDarkMode } = useTheme$1();
114041
+ /** Returns set of "evaluatorId:metricName" for all metrics in the evaluation. */ function getMetricKeys(evaluation) {
114042
+ const keys = new Set();
114043
+ for (const evaluator of evaluation.evaluators){
114044
+ for (const metric of evaluator.metrics){
114045
+ keys.add(`${evaluator.evaluator_id}:${metric.name}`);
114046
+ }
114047
+ }
114048
+ return keys;
114049
+ }
114050
+ /**
114051
+ * Returns true if both evaluations have the same set of metrics
114052
+ * (evaluator_id + metric name) across all evaluators.
114053
+ */ function evaluationsHaveSameMetrics(a, b) {
114054
+ if (a == null || b == null) return false;
114055
+ const evalA = isEvaluationDto(a) ? transformEvaluation(a) : a;
114056
+ const evalB = isEvaluationDto(b) ? transformEvaluation(b) : b;
114057
+ const keysA = getMetricKeys(evalA);
114058
+ const keysB = getMetricKeys(evalB);
114059
+ if (keysA.size !== keysB.size) return false;
114060
+ for (const key of keysA){
114061
+ if (!keysB.has(key)) return false;
114062
+ }
114063
+ return true;
114064
+ }
114065
+
114066
+ function formatMetricValue(evaluation, evaluatorId, metricName, metricType, options) {
114067
+ const evaluatorResults = evaluation.results[evaluatorId];
114068
+ const value = evaluatorResults?.[metricName];
114069
+ if (value === undefined) return "-";
114070
+ if (metricType === "Categorical" && options?.length) {
114071
+ const index = Math.round(value);
114072
+ return options[index] || value.toString();
114073
+ }
114074
+ if (metricType === "Continuous") {
114075
+ return value.toFixed(1);
114076
+ }
114077
+ return value.toString();
114078
+ }
114079
+ function getMetricValue(evaluation, evaluatorId, metricName) {
114080
+ const evaluatorResults = evaluation.results[evaluatorId];
114081
+ return evaluatorResults?.[metricName];
114082
+ }
114083
+ const EvaluationsCompareView = ({ evaluations, evaluationId1, evaluationId2, onEvaluationId1Change, onEvaluationId2Change, loading = false, showEvaluationComparisonDropdowns = false, backHref })=>{
114084
+ const { theme } = useTheme$1();
113557
114085
  const normalizedEvaluations = React__default.useMemo(()=>evaluations.map((e)=>isEvaluationDto(e) ? transformEvaluation(e) : e), [
113558
114086
  evaluations
113559
114087
  ]);
113560
- // Handler for copying evaluation IDs to clipboard
113561
- const handleCopyIds = async ()=>{
113562
- if (!sourceEvaluationId || !targetEvaluationId) {
113563
- staticMethods.error("No evaluation IDs available");
113564
- return;
113565
- }
113566
- try {
113567
- const idsText = `Source: ${sourceEvaluationId}\nTarget: ${targetEvaluationId}`;
113568
- await navigator.clipboard.writeText(idsText);
113569
- staticMethods.success("Evaluation IDs copied to clipboard");
113570
- } catch (err) {
113571
- staticMethods.error("Failed to copy evaluation IDs");
113572
- }
113573
- };
113574
- // Handler for sharing evaluation comparison
113575
- const handleShare = async ()=>{
113576
- if (!sourceEvaluationId || !targetEvaluationId) {
113577
- staticMethods.error("No evaluations available to share");
113578
- return;
113579
- }
113580
- const shareUrl = `${window.location.origin}${window.location.pathname}#/evaluations/compare?source=${sourceEvaluationId}&target=${targetEvaluationId}`;
113581
- // Try Web Share API if available
113582
- if (navigator.share) {
113583
- try {
113584
- await navigator.share({
113585
- title: "Evaluation Comparison",
113586
- text: `Compare evaluations: ${sourceEvaluationId} vs ${targetEvaluationId}`,
113587
- url: shareUrl
114088
+ const evaluation1 = normalizedEvaluations.find((e)=>e.evaluation_id === evaluationId1);
114089
+ const evaluation2 = normalizedEvaluations.find((e)=>e.evaluation_id === evaluationId2);
114090
+ const metricsMismatch = React__default.useMemo(()=>!evaluationsHaveSameMetrics(evaluation1, evaluation2), [
114091
+ evaluation1,
114092
+ evaluation2
114093
+ ]);
114094
+ const comparisonData = React__default.useMemo(()=>{
114095
+ if (!evaluation1 || !evaluation2) return [];
114096
+ const rows = [];
114097
+ // Build evaluator lookup by id for evaluation2 (to match evaluators between evaluations)
114098
+ const eval2EvaluatorsById = new Map(evaluation2.evaluators.map((e)=>[
114099
+ e.evaluator_id,
114100
+ e
114101
+ ]));
114102
+ // Iterate over ALL evaluators in evaluation1 (LLM, Tool, Judge, etc.)
114103
+ for (const evaluator1 of evaluation1.evaluators){
114104
+ const evaluator2 = eval2EvaluatorsById.get(evaluator1.evaluator_id);
114105
+ if (!evaluator2) continue;
114106
+ const allMetricNames = new Set();
114107
+ evaluator1.metrics.forEach((m)=>allMetricNames.add(m.name));
114108
+ evaluator2.metrics.forEach((m)=>allMetricNames.add(m.name));
114109
+ for (const metricName of allMetricNames){
114110
+ const metric1 = evaluator1.metrics.find((m)=>m.name === metricName);
114111
+ const metric2 = evaluator2.metrics.find((m)=>m.name === metricName);
114112
+ const metricType = metric1?.type || metric2?.type || "Continuous";
114113
+ const options = metric1?.type === "Categorical" ? metric1.options : metric2?.type === "Categorical" ? metric2.options : undefined;
114114
+ const value1 = getMetricValue(evaluation1, evaluator1.evaluator_id, metricName);
114115
+ const value2 = getMetricValue(evaluation2, evaluator2.evaluator_id, metricName);
114116
+ const formatted1 = formatMetricValue(evaluation1, evaluator1.evaluator_id, metricName, metricType, options);
114117
+ const formatted2 = formatMetricValue(evaluation2, evaluator2.evaluator_id, metricName, metricType, options);
114118
+ let difference;
114119
+ if (metricType === "Continuous" && value1 !== undefined && value2 !== undefined) {
114120
+ difference = value2 - value1;
114121
+ }
114122
+ rows.push({
114123
+ metricName,
114124
+ evaluatorName: evaluator1.name,
114125
+ metricType,
114126
+ value1,
114127
+ value2,
114128
+ formatted1,
114129
+ formatted2,
114130
+ difference,
114131
+ rowKey: `${evaluator1.evaluator_id}:${metricName}`
113588
114132
  });
113589
- return;
113590
- } catch (err) {
113591
- // User cancelled or error occurred, fall back to clipboard
113592
114133
  }
113593
114134
  }
113594
- // Fall back to copying URL to clipboard
113595
- try {
113596
- await navigator.clipboard.writeText(shareUrl);
113597
- staticMethods.success("Share link copied to clipboard");
113598
- } catch (err) {
113599
- staticMethods.error("Failed to copy share link");
113600
- }
113601
- };
113602
- // Find the evaluations
113603
- const sourceEvaluation = normalizedEvaluations.find((e)=>e.evaluation_id === sourceEvaluationId);
113604
- const targetEvaluation = normalizedEvaluations.find((e)=>e.evaluation_id === targetEvaluationId);
113605
- // Helper to format metric value (same logic as evaluations.tsx)
113606
- const formatMetricValue = (evaluation, metricName)=>{
113607
- const evaluator = evaluation.evaluators[0];
113608
- const metric = evaluator?.metrics.find((m)=>m.name === metricName);
113609
- const evaluatorId = evaluator?.evaluator_id || "";
113610
- const evaluatorResults = evaluation.results[evaluatorId];
113611
- const value = evaluatorResults?.[metricName];
113612
- if (value === undefined) return "-";
113613
- if (metric?.type === "Categorical" && metric.options) {
113614
- const index = Math.round(value);
113615
- return metric.options[index] || value.toString();
113616
- }
113617
- if (metric?.type === "Continuous") {
113618
- return value.toFixed(1);
113619
- }
113620
- return value.toString();
113621
- };
113622
- // Get metric value as number for comparison
113623
- const getMetricValue = (evaluation, metricName)=>{
113624
- const evaluator = evaluation.evaluators[0];
113625
- const evaluatorId = evaluator?.evaluator_id || "";
113626
- const evaluatorResults = evaluation.results[evaluatorId];
113627
- return evaluatorResults?.[metricName];
113628
- };
113629
- // Build comparison data
113630
- const comparisonData = React__default.useMemo(()=>{
113631
- if (!sourceEvaluation || !targetEvaluation) return [];
113632
- const sourceEvaluator = sourceEvaluation.evaluators[0];
113633
- const targetEvaluator = targetEvaluation.evaluators[0];
113634
- if (!sourceEvaluator || !targetEvaluator) return [];
113635
- // Get all unique metric names
113636
- const allMetricNames = new Set();
113637
- sourceEvaluator.metrics.forEach((m)=>allMetricNames.add(m.name));
113638
- targetEvaluator.metrics.forEach((m)=>allMetricNames.add(m.name));
113639
- return Array.from(allMetricNames).map((metricName)=>{
113640
- const sourceMetric = sourceEvaluator.metrics.find((m)=>m.name === metricName);
113641
- const targetMetric = targetEvaluator.metrics.find((m)=>m.name === metricName);
113642
- const metricType = sourceMetric?.type || targetMetric?.type || "Continuous";
113643
- const sourceValue = getMetricValue(sourceEvaluation, metricName);
113644
- const targetValue = getMetricValue(targetEvaluation, metricName);
113645
- const sourceFormatted = formatMetricValue(sourceEvaluation, metricName);
113646
- const targetFormatted = formatMetricValue(targetEvaluation, metricName);
113647
- let difference;
113648
- if (metricType === "Continuous" && sourceValue !== undefined && targetValue !== undefined) {
113649
- difference = targetValue - sourceValue;
113650
- }
113651
- return {
113652
- metricName,
113653
- metricType,
113654
- sourceValue,
113655
- targetValue,
113656
- sourceFormatted,
113657
- targetFormatted,
113658
- difference
113659
- };
114135
+ return rows;
114136
+ }, [
114137
+ evaluation1,
114138
+ evaluation2
114139
+ ]);
114140
+ const allValuesIdentical = React__default.useMemo(()=>{
114141
+ if (comparisonData.length === 0) return false;
114142
+ return comparisonData.every((r)=>{
114143
+ if (r.metricType === "Continuous" && r.difference !== undefined) return r.difference === 0;
114144
+ return r.formatted1 === r.formatted2;
113660
114145
  });
113661
114146
  }, [
113662
- sourceEvaluation,
113663
- targetEvaluation
114147
+ comparisonData
113664
114148
  ]);
113665
- // Prepare options for dropdowns
113666
114149
  const evaluationOptions = React__default.useMemo(()=>{
113667
114150
  return normalizedEvaluations.map((evaluation)=>({
113668
114151
  label: `${evaluation.name || "Unnamed Evaluation"} (${evaluation.agent_name})`,
@@ -113679,54 +114162,261 @@ const EvaluationsCompare = ({ open, onClose, sourceEvaluationId, targetEvaluatio
113679
114162
  width: 200,
113680
114163
  render: (name, record)=>/*#__PURE__*/ React__default.createElement("div", null, /*#__PURE__*/ React__default.createElement("div", {
113681
114164
  style: {
113682
- fontWeight: 500
114165
+ fontWeight: theme.fontWeight.medium
113683
114166
  }
113684
114167
  }, name), /*#__PURE__*/ React__default.createElement("div", {
113685
114168
  style: {
113686
- fontSize: "12px",
113687
- color: isDarkMode ? "#8c8c8c" : "#595959"
114169
+ fontSize: theme.fontSize.xs,
114170
+ color: theme.colors.mutedForeground
113688
114171
  }
113689
- }, record.metricType))
114172
+ }, record.evaluatorName, " • ", record.metricType))
113690
114173
  },
113691
114174
  {
113692
- title: sourceEvaluation?.name || "Source",
113693
- key: "source",
114175
+ title: evaluation1?.name || "Evaluation 1",
114176
+ key: "evaluation1",
113694
114177
  width: 150,
113695
114178
  render: (_, record)=>/*#__PURE__*/ React__default.createElement("div", null, /*#__PURE__*/ React__default.createElement(Tag, {
113696
114179
  color: "blue"
113697
- }, record.sourceFormatted))
114180
+ }, record.formatted1))
113698
114181
  },
113699
114182
  {
113700
- title: targetEvaluation?.name || "Target",
113701
- key: "target",
114183
+ title: evaluation2?.name || "Evaluation 2",
114184
+ key: "evaluation2",
113702
114185
  width: 150,
113703
114186
  render: (_, record)=>/*#__PURE__*/ React__default.createElement("div", null, /*#__PURE__*/ React__default.createElement(Tag, {
113704
114187
  color: "green"
113705
- }, record.targetFormatted))
114188
+ }, record.formatted2))
113706
114189
  },
113707
114190
  {
113708
114191
  title: "Difference",
113709
114192
  key: "difference",
113710
114193
  width: 120,
113711
114194
  render: (_, record)=>{
113712
- if (record.difference === undefined) return "-";
113713
- const isPositive = record.difference > 0;
113714
- const isNegative = record.difference < 0;
113715
- return /*#__PURE__*/ React__default.createElement(Tag, {
113716
- color: isPositive ? "green" : isNegative ? "red" : "default"
113717
- }, isPositive ? "+" : "", record.difference.toFixed(1));
114195
+ if (record.difference !== undefined) {
114196
+ const isPositive = record.difference > 0;
114197
+ const isNegative = record.difference < 0;
114198
+ return /*#__PURE__*/ React__default.createElement(Tag, {
114199
+ color: isPositive ? "green" : isNegative ? "red" : "default"
114200
+ }, isPositive ? "+" : "", record.difference.toFixed(1));
114201
+ }
114202
+ // Categorical: show "Different" when values differ
114203
+ if (record.formatted1 !== record.formatted2) {
114204
+ return /*#__PURE__*/ React__default.createElement(Tag, {
114205
+ color: "orange"
114206
+ }, "Different");
114207
+ }
114208
+ return "-";
113718
114209
  }
113719
114210
  }
113720
114211
  ];
113721
- const extraButtonsIconSize = 24;
114212
+ const evaluation1Label = evaluation1 ? `${evaluation1.name || "Unnamed Evaluation"} (${evaluation1.agent_name})` : "Select evaluation 1";
114213
+ const evaluation2Label = evaluation2 ? `${evaluation2.name || "Unnamed Evaluation"} (${evaluation2.agent_name})` : "Select evaluation 2";
114214
+ return /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, backHref && /*#__PURE__*/ React__default.createElement("a", {
114215
+ href: backHref,
114216
+ style: {
114217
+ display: "inline-flex",
114218
+ alignItems: "center",
114219
+ gap: 6,
114220
+ marginBottom: 24,
114221
+ color: theme.colors.mutedForeground,
114222
+ textDecoration: "none",
114223
+ fontSize: 14
114224
+ }
114225
+ }, /*#__PURE__*/ React__default.createElement(ArrowLeft, {
114226
+ size: 16
114227
+ }), "Back to Evaluations"), /*#__PURE__*/ React__default.createElement("div", {
114228
+ style: {
114229
+ marginBottom: theme.spacing.md,
114230
+ color: theme.colors.mutedForeground
114231
+ }
114232
+ }, showEvaluationComparisonDropdowns ? "Select two evaluations to compare their metrics" : /*#__PURE__*/ React__default.createElement("div", {
114233
+ style: {
114234
+ display: "flex",
114235
+ alignItems: "center",
114236
+ gap: theme.spacing.sm,
114237
+ flexWrap: "wrap"
114238
+ }
114239
+ }, /*#__PURE__*/ React__default.createElement("span", null, /*#__PURE__*/ React__default.createElement("strong", null, "Evaluation 1:"), " ", evaluation1Label), /*#__PURE__*/ React__default.createElement("span", {
114240
+ style: {
114241
+ color: theme.colors.border
114242
+ }
114243
+ }, "•"), /*#__PURE__*/ React__default.createElement("span", null, /*#__PURE__*/ React__default.createElement("strong", null, "Evaluation 2:"), " ", evaluation2Label))), showEvaluationComparisonDropdowns && /*#__PURE__*/ React__default.createElement("div", {
114244
+ style: {
114245
+ marginBottom: theme.spacing.lg
114246
+ }
114247
+ }, /*#__PURE__*/ React__default.createElement(Space, {
114248
+ size: "middle",
114249
+ style: {
114250
+ width: "100%"
114251
+ }
114252
+ }, /*#__PURE__*/ React__default.createElement("div", {
114253
+ style: {
114254
+ flex: 1
114255
+ }
114256
+ }, /*#__PURE__*/ React__default.createElement("label", {
114257
+ style: {
114258
+ display: "block",
114259
+ marginBottom: theme.spacing.sm,
114260
+ fontWeight: theme.fontWeight.medium,
114261
+ color: theme.colors.foreground
114262
+ }
114263
+ }, "Evaluation 1"), /*#__PURE__*/ React__default.createElement(Select, {
114264
+ style: {
114265
+ width: "100%"
114266
+ },
114267
+ placeholder: "Select evaluation 1",
114268
+ value: evaluationId1,
114269
+ onChange: (value)=>onEvaluationId1Change(value),
114270
+ options: evaluationOptions,
114271
+ showSearch: true,
114272
+ loading: loading,
114273
+ filterOption: (input, option)=>(option?.label ?? "").toLowerCase().includes(input.toLowerCase())
114274
+ })), /*#__PURE__*/ React__default.createElement("div", {
114275
+ style: {
114276
+ flex: 1
114277
+ }
114278
+ }, /*#__PURE__*/ React__default.createElement("label", {
114279
+ style: {
114280
+ display: "block",
114281
+ marginBottom: theme.spacing.sm,
114282
+ fontWeight: theme.fontWeight.medium,
114283
+ color: theme.colors.foreground
114284
+ }
114285
+ }, "Evaluation 2"), /*#__PURE__*/ React__default.createElement(Select, {
114286
+ style: {
114287
+ width: "100%"
114288
+ },
114289
+ placeholder: "Select evaluation 2",
114290
+ value: evaluationId2,
114291
+ onChange: (value)=>onEvaluationId2Change(value),
114292
+ options: evaluationOptions,
114293
+ showSearch: true,
114294
+ loading: loading,
114295
+ filterOption: (input, option)=>(option?.label ?? "").toLowerCase().includes(input.toLowerCase())
114296
+ })))), !evaluation1 || !evaluation2 ? /*#__PURE__*/ React__default.createElement("div", {
114297
+ style: {
114298
+ textAlign: "center",
114299
+ padding: theme.spacing["2xl"],
114300
+ color: theme.colors.mutedForeground
114301
+ }
114302
+ }, /*#__PURE__*/ React__default.createElement("p", null, "Please select both evaluations to compare")) : metricsMismatch ? /*#__PURE__*/ React__default.createElement(Alert, {
114303
+ type: "error",
114304
+ showIcon: true,
114305
+ message: "Cannot compare evaluations",
114306
+ description: "The two evaluations must have the same metrics in order to be diffed. Please select evaluations that share the same metric set."
114307
+ }) : /*#__PURE__*/ React__default.createElement("div", null, allValuesIdentical && /*#__PURE__*/ React__default.createElement(Alert, {
114308
+ type: "info",
114309
+ showIcon: true,
114310
+ message: "Evaluations are identical",
114311
+ description: "All metric values match between the two evaluations.",
114312
+ style: {
114313
+ marginBottom: theme.spacing.lg
114314
+ }
114315
+ }), /*#__PURE__*/ React__default.createElement("div", {
114316
+ style: {
114317
+ display: "grid",
114318
+ gridTemplateColumns: "1fr 1fr",
114319
+ gap: theme.spacing.lg,
114320
+ marginBottom: theme.spacing.lg,
114321
+ padding: theme.spacing.md,
114322
+ borderRadius: theme.borderRadius.lg,
114323
+ border: `1px solid ${theme.colors.border}`,
114324
+ backgroundColor: theme.colors.muted
114325
+ }
114326
+ }, /*#__PURE__*/ React__default.createElement("div", null, /*#__PURE__*/ React__default.createElement("h3", {
114327
+ style: {
114328
+ margin: `0 0 ${theme.spacing.sm} 0`,
114329
+ fontSize: theme.fontSize.base,
114330
+ fontWeight: theme.fontWeight.semibold
114331
+ }
114332
+ }, "Evaluation 1: ", evaluation1.name || "Unnamed Evaluation"), /*#__PURE__*/ React__default.createElement("div", {
114333
+ style: {
114334
+ fontSize: theme.fontSize.sm,
114335
+ color: theme.colors.mutedForeground
114336
+ }
114337
+ }, /*#__PURE__*/ React__default.createElement("div", null, "Agent: ", evaluation1.agent_name), /*#__PURE__*/ React__default.createElement("div", null, "Runs: ", evaluation1.runs.length), /*#__PURE__*/ React__default.createElement("div", null, "Created: ", moment(evaluation1.created_at).format("YYYY-MM-DD HH:mm:ss")))), /*#__PURE__*/ React__default.createElement("div", null, /*#__PURE__*/ React__default.createElement("h3", {
114338
+ style: {
114339
+ margin: `0 0 ${theme.spacing.sm} 0`,
114340
+ fontSize: theme.fontSize.base,
114341
+ fontWeight: theme.fontWeight.semibold
114342
+ }
114343
+ }, "Evaluation 2: ", evaluation2.name || "Unnamed Evaluation"), /*#__PURE__*/ React__default.createElement("div", {
114344
+ style: {
114345
+ fontSize: theme.fontSize.sm,
114346
+ color: theme.colors.mutedForeground
114347
+ }
114348
+ }, /*#__PURE__*/ React__default.createElement("div", null, "Agent: ", evaluation2.agent_name), /*#__PURE__*/ React__default.createElement("div", null, "Runs: ", evaluation2.runs.length), /*#__PURE__*/ React__default.createElement("div", null, "Created: ", moment(evaluation2.created_at).format("YYYY-MM-DD HH:mm:ss"))))), /*#__PURE__*/ React__default.createElement("h3", {
114349
+ style: {
114350
+ margin: `0 0 ${theme.spacing.md} 0`,
114351
+ fontSize: theme.fontSize.lg,
114352
+ fontWeight: theme.fontWeight.semibold
114353
+ }
114354
+ }, "Metrics Comparison"), /*#__PURE__*/ React__default.createElement(ForwardTable, {
114355
+ columns: comparisonColumns,
114356
+ dataSource: comparisonData,
114357
+ rowKey: "rowKey",
114358
+ pagination: false,
114359
+ style: {
114360
+ background: theme.colors.card
114361
+ },
114362
+ rowClassName: (record)=>{
114363
+ const hasDiff = record.metricType === "Continuous" ? record.difference !== undefined && record.difference !== 0 : record.formatted1 !== record.formatted2;
114364
+ return hasDiff ? "evaluations-compare-diff-row" : "";
114365
+ }
114366
+ })));
114367
+ };
114368
+
114369
+ const extraButtonsIconSize = 24;
114370
+ const EvaluationsCompareDrawer = ({ open, onClose, evaluationId1, evaluationId2, evaluations, onEvaluationId1Change, onEvaluationId2Change })=>{
114371
+ const handleCopyIds = async ()=>{
114372
+ if (!evaluationId1 || !evaluationId2) {
114373
+ staticMethods.error("No evaluation IDs available");
114374
+ return;
114375
+ }
114376
+ try {
114377
+ const idsText = `Evaluation 1: ${evaluationId1}\nEvaluation 2: ${evaluationId2}`;
114378
+ await navigator.clipboard.writeText(idsText);
114379
+ staticMethods.success("Evaluation IDs copied to clipboard");
114380
+ } catch (err) {
114381
+ staticMethods.error("Failed to copy evaluation IDs");
114382
+ }
114383
+ };
114384
+ const handleShare = async ()=>{
114385
+ if (!evaluationId1 || !evaluationId2) {
114386
+ staticMethods.error("No evaluations available to share");
114387
+ return;
114388
+ }
114389
+ const shareUrl = `${window.location.origin}${window.location.pathname}#/evaluations?compare=${evaluationId1},${evaluationId2}`;
114390
+ if (navigator.share) {
114391
+ try {
114392
+ await navigator.share({
114393
+ title: "Evaluation Comparison",
114394
+ text: `Compare evaluations: ${evaluationId1} vs ${evaluationId2}`,
114395
+ url: shareUrl
114396
+ });
114397
+ return;
114398
+ } catch (err) {
114399
+ // User cancelled or error occurred, fall back to clipboard
114400
+ }
114401
+ }
114402
+ try {
114403
+ await navigator.clipboard.writeText(shareUrl);
114404
+ staticMethods.success("Share link copied to clipboard");
114405
+ } catch (err) {
114406
+ staticMethods.error("Failed to copy share link");
114407
+ }
114408
+ };
113722
114409
  return /*#__PURE__*/ React__default.createElement(Drawer$2, {
113723
114410
  title: "Compare Evaluations",
113724
114411
  placement: "right",
113725
114412
  size: "60%",
113726
114413
  open: open,
113727
114414
  onClose: onClose,
113728
- extra: /*#__PURE__*/ React__default.createElement(Space, {
113729
- size: "middle"
114415
+ extra: /*#__PURE__*/ React__default.createElement("div", {
114416
+ style: {
114417
+ display: "flex",
114418
+ gap: 8
114419
+ }
113730
114420
  }, /*#__PURE__*/ React__default.createElement(Tooltip, {
113731
114421
  title: "Copy IDs to Clipboard"
113732
114422
  }, /*#__PURE__*/ React__default.createElement(Button$1, {
@@ -113735,7 +114425,7 @@ const EvaluationsCompare = ({ open, onClose, sourceEvaluationId, targetEvaluatio
113735
114425
  size: extraButtonsIconSize
113736
114426
  }),
113737
114427
  onClick: handleCopyIds,
113738
- disabled: !sourceEvaluationId || !targetEvaluationId
114428
+ disabled: !evaluationId1 || !evaluationId2
113739
114429
  })), /*#__PURE__*/ React__default.createElement(Tooltip, {
113740
114430
  title: "Share"
113741
114431
  }, /*#__PURE__*/ React__default.createElement(Button$1, {
@@ -113744,123 +114434,21 @@ const EvaluationsCompare = ({ open, onClose, sourceEvaluationId, targetEvaluatio
113744
114434
  size: extraButtonsIconSize
113745
114435
  }),
113746
114436
  onClick: handleShare,
113747
- disabled: !sourceEvaluationId || !targetEvaluationId
114437
+ disabled: !evaluationId1 || !evaluationId2
113748
114438
  }))),
113749
114439
  styles: {
113750
114440
  body: {
113751
114441
  padding: "24px"
113752
114442
  }
113753
114443
  }
113754
- }, /*#__PURE__*/ React__default.createElement("div", {
113755
- style: {
113756
- marginBottom: "16px",
113757
- color: isDarkMode ? "#8c8c8c" : "#595959"
113758
- }
113759
- }, "Select two evaluations to compare their metrics"), /*#__PURE__*/ React__default.createElement("div", {
113760
- style: {
113761
- marginBottom: "24px"
113762
- }
113763
- }, /*#__PURE__*/ React__default.createElement(Space, {
113764
- size: "middle",
113765
- style: {
113766
- width: "100%"
113767
- }
113768
- }, /*#__PURE__*/ React__default.createElement("div", {
113769
- style: {
113770
- flex: 1
113771
- }
113772
- }, /*#__PURE__*/ React__default.createElement("label", {
113773
- style: {
113774
- display: "block",
113775
- marginBottom: "8px",
113776
- fontWeight: 500,
113777
- color: isDarkMode ? "#e5e7eb" : "#1f2937"
113778
- }
113779
- }, "Source Evaluation"), /*#__PURE__*/ React__default.createElement(Select, {
113780
- style: {
113781
- width: "100%"
113782
- },
113783
- placeholder: "Select source evaluation",
113784
- value: sourceEvaluationId,
113785
- onChange: (value)=>onSourceChange(value),
113786
- options: evaluationOptions,
113787
- showSearch: true,
113788
- filterOption: (input, option)=>(option?.label ?? "").toLowerCase().includes(input.toLowerCase())
113789
- })), /*#__PURE__*/ React__default.createElement("div", {
113790
- style: {
113791
- flex: 1
113792
- }
113793
- }, /*#__PURE__*/ React__default.createElement("label", {
113794
- style: {
113795
- display: "block",
113796
- marginBottom: "8px",
113797
- fontWeight: 500,
113798
- color: isDarkMode ? "#e5e7eb" : "#1f2937"
113799
- }
113800
- }, "Target Evaluation"), /*#__PURE__*/ React__default.createElement(Select, {
113801
- style: {
113802
- width: "100%"
113803
- },
113804
- placeholder: "Select target evaluation",
113805
- value: targetEvaluationId,
113806
- onChange: (value)=>onTargetChange(value),
113807
- options: evaluationOptions,
113808
- showSearch: true,
113809
- filterOption: (input, option)=>(option?.label ?? "").toLowerCase().includes(input.toLowerCase())
113810
- })))), !sourceEvaluation || !targetEvaluation ? /*#__PURE__*/ React__default.createElement("div", {
113811
- style: {
113812
- textAlign: "center",
113813
- padding: "48px",
113814
- color: isDarkMode ? "#8c8c8c" : "#595959"
113815
- }
113816
- }, /*#__PURE__*/ React__default.createElement("p", null, "Please select both source and target evaluations to compare")) : /*#__PURE__*/ React__default.createElement("div", null, /*#__PURE__*/ React__default.createElement("div", {
113817
- style: {
113818
- display: "grid",
113819
- gridTemplateColumns: "1fr 1fr",
113820
- gap: "24px",
113821
- marginBottom: "24px",
113822
- padding: "16px",
113823
- borderRadius: "8px",
113824
- border: `1px solid ${isDarkMode ? "#2d2d2d" : "#e5e7eb"}`,
113825
- backgroundColor: isDarkMode ? "#1a1a1a" : "#f9fafb"
113826
- }
113827
- }, /*#__PURE__*/ React__default.createElement("div", null, /*#__PURE__*/ React__default.createElement("h3", {
113828
- style: {
113829
- margin: "0 0 12px 0",
113830
- fontSize: "16px",
113831
- fontWeight: 600
113832
- }
113833
- }, "Source: ", sourceEvaluation.name || "Unnamed Evaluation"), /*#__PURE__*/ React__default.createElement("div", {
113834
- style: {
113835
- fontSize: "14px",
113836
- color: isDarkMode ? "#a3a3a3" : "#6b7280"
113837
- }
113838
- }, /*#__PURE__*/ React__default.createElement("div", null, "Agent: ", sourceEvaluation.agent_name), /*#__PURE__*/ React__default.createElement("div", null, "Runs: ", sourceEvaluation.runs.length), /*#__PURE__*/ React__default.createElement("div", null, "Created: ", moment(sourceEvaluation.created_at).format("YYYY-MM-DD HH:mm:ss")))), /*#__PURE__*/ React__default.createElement("div", null, /*#__PURE__*/ React__default.createElement("h3", {
113839
- style: {
113840
- margin: "0 0 12px 0",
113841
- fontSize: "16px",
113842
- fontWeight: 600
113843
- }
113844
- }, "Target: ", targetEvaluation.name || "Unnamed Evaluation"), /*#__PURE__*/ React__default.createElement("div", {
113845
- style: {
113846
- fontSize: "14px",
113847
- color: isDarkMode ? "#a3a3a3" : "#6b7280"
113848
- }
113849
- }, /*#__PURE__*/ React__default.createElement("div", null, "Agent: ", targetEvaluation.agent_name), /*#__PURE__*/ React__default.createElement("div", null, "Runs: ", targetEvaluation.runs.length), /*#__PURE__*/ React__default.createElement("div", null, "Created: ", moment(targetEvaluation.created_at).format("YYYY-MM-DD HH:mm:ss"))))), /*#__PURE__*/ React__default.createElement("h3", {
113850
- style: {
113851
- margin: "0 0 16px 0",
113852
- fontSize: "18px",
113853
- fontWeight: 600
113854
- }
113855
- }, "Metrics Comparison"), /*#__PURE__*/ React__default.createElement(ForwardTable, {
113856
- columns: comparisonColumns,
113857
- dataSource: comparisonData,
113858
- rowKey: "metricName",
113859
- pagination: false,
113860
- style: {
113861
- background: isDarkMode ? "#141414" : "#fff"
113862
- }
113863
- })));
114444
+ }, /*#__PURE__*/ React__default.createElement(EvaluationsCompareView, {
114445
+ evaluations: evaluations,
114446
+ evaluationId1: evaluationId1,
114447
+ evaluationId2: evaluationId2,
114448
+ onEvaluationId1Change: onEvaluationId1Change,
114449
+ onEvaluationId2Change: onEvaluationId2Change,
114450
+ showEvaluationComparisonDropdowns: false
114451
+ }));
113864
114452
  };
113865
114453
 
113866
114454
  const defaultGetEvaluatorResultsHref = (evaluationId, evaluatorId)=>`#/evaluations/${evaluationId}/results/${evaluatorId}`;
@@ -114094,17 +114682,19 @@ const EvaluationDetailsDrawer = ({ evaluation, open, onClose, getEvaluatorResult
114094
114682
  })))));
114095
114683
  };
114096
114684
 
114097
- const EvaluationsTable = ({ evaluations, loading = false, error = null, onRefresh, onRowClick, onCompare, showFilters = true, showCompare = true, emptyMessage, title })=>{
114685
+ const EvaluationsTable = ({ evaluations, loading = false, error = null, onRefresh, onRowClick, onCompare, compareIdsFromUrl, onCompareUrlChange, showFilters = true, showCompare = true, emptyMessage, title, pagination: serverPagination, onFiltersChange, onFetchEvaluationsByIds })=>{
114098
114686
  const { theme } = useTheme$1();
114099
114687
  const [selectedAgents, setSelectedAgents] = useState([]);
114100
114688
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);
114101
114689
  const [compareDrawerOpen, setCompareDrawerOpen] = useState(false);
114102
- const [sourceEvaluationId, setSourceEvaluationId] = useState(null);
114103
- const [targetEvaluationId, setTargetEvaluationId] = useState(null);
114690
+ const [evaluationId1, setEvaluationId1] = useState(null);
114691
+ const [evaluationId2, setEvaluationId2] = useState(null);
114104
114692
  const [selectedEvaluation, setSelectedEvaluation] = useState(null);
114105
114693
  const [detailsDrawerOpen, setDetailsDrawerOpen] = useState(false);
114106
114694
  const [pageSize, setPageSize] = useState(50);
114107
114695
  const [selectedMetricFilter, setSelectedMetricFilter] = useState(null);
114696
+ const [drawerEvaluations, setDrawerEvaluations] = useState([]);
114697
+ const isServerPagination = !!serverPagination;
114108
114698
  const normalized = useMemo(()=>evaluations.map((e)=>isEvaluationDto(e) ? transformEvaluation(e) : e), [
114109
114699
  evaluations
114110
114700
  ]);
@@ -114153,6 +114743,63 @@ const EvaluationsTable = ({ evaluations, loading = false, error = null, onRefres
114153
114743
  selectedAgents,
114154
114744
  selectedMetricFilter
114155
114745
  ]);
114746
+ const tableDataSource = filteredEvaluations;
114747
+ const compareDrawerEvaluations = useMemo(()=>{
114748
+ if (drawerEvaluations.length === 0) return normalized;
114749
+ const byId = new Map(normalized.map((e)=>[
114750
+ e.evaluation_id,
114751
+ e
114752
+ ]));
114753
+ for (const e of drawerEvaluations){
114754
+ const id = e.evaluation_id ?? e.evaluation_id;
114755
+ if (id && !byId.has(id)) byId.set(id, e);
114756
+ }
114757
+ return Array.from(byId.values());
114758
+ }, [
114759
+ normalized,
114760
+ drawerEvaluations
114761
+ ]);
114762
+ // Sync drawer when compare param comes from URL
114763
+ useEffect(()=>{
114764
+ if (compareIdsFromUrl) {
114765
+ setEvaluationId1(compareIdsFromUrl[0]);
114766
+ setEvaluationId2(compareIdsFromUrl[1]);
114767
+ setCompareDrawerOpen(true);
114768
+ }
114769
+ }, [
114770
+ compareIdsFromUrl
114771
+ ]);
114772
+ // Fetch evaluations by ID for compare drawer when opened from URL (server pagination)
114773
+ useEffect(()=>{
114774
+ if (!compareDrawerOpen || !onFetchEvaluationsByIds || !evaluationId1 || !evaluationId2) {
114775
+ setDrawerEvaluations([]);
114776
+ return;
114777
+ }
114778
+ const ids = [
114779
+ evaluationId1,
114780
+ evaluationId2
114781
+ ];
114782
+ const inNormalized = ids.every((id)=>normalized.some((e)=>e.evaluation_id === id));
114783
+ if (inNormalized) {
114784
+ setDrawerEvaluations([]);
114785
+ return;
114786
+ }
114787
+ let cancelled = false;
114788
+ onFetchEvaluationsByIds(ids).then((fetched)=>{
114789
+ if (!cancelled) {
114790
+ setDrawerEvaluations(fetched);
114791
+ }
114792
+ });
114793
+ return ()=>{
114794
+ cancelled = true;
114795
+ };
114796
+ }, [
114797
+ compareDrawerOpen,
114798
+ evaluationId1,
114799
+ evaluationId2,
114800
+ normalized,
114801
+ onFetchEvaluationsByIds
114802
+ ]);
114156
114803
  // Handle row selection - limit to 2 rows
114157
114804
  const handleRowSelectionChange = (selectedKeys)=>{
114158
114805
  if (selectedKeys.length <= 2) {
@@ -114164,14 +114811,23 @@ const EvaluationsTable = ({ evaluations, loading = false, error = null, onRefres
114164
114811
  if (selectedRowKeys.length === 2 && onCompare) {
114165
114812
  onCompare(selectedRowKeys[0], selectedRowKeys[1]);
114166
114813
  } else if (selectedRowKeys.length === 2 && !onCompare) {
114167
- setSourceEvaluationId(selectedRowKeys[0]);
114168
- setTargetEvaluationId(selectedRowKeys[1]);
114814
+ setEvaluationId1(selectedRowKeys[0]);
114815
+ setEvaluationId2(selectedRowKeys[1]);
114169
114816
  setCompareDrawerOpen(true);
114170
114817
  }
114171
114818
  };
114172
114819
  // Handle drawer close
114173
114820
  const handleDrawerClose = ()=>{
114174
114821
  setCompareDrawerOpen(false);
114822
+ onCompareUrlChange?.(null, null);
114823
+ };
114824
+ const handleEvaluationId1Change = (id)=>{
114825
+ setEvaluationId1(id);
114826
+ onCompareUrlChange?.(id, evaluationId2);
114827
+ };
114828
+ const handleEvaluationId2Change = (id)=>{
114829
+ setEvaluationId2(id);
114830
+ onCompareUrlChange?.(evaluationId1, id);
114175
114831
  };
114176
114832
  // Handle row click to open evaluation details
114177
114833
  const handleRowClick = (record)=>{
@@ -114295,7 +114951,12 @@ const EvaluationsTable = ({ evaluations, loading = false, error = null, onRefres
114295
114951
  placeholder: "Filter by Agent",
114296
114952
  allowClear: true,
114297
114953
  value: selectedAgents,
114298
- onChange: setSelectedAgents,
114954
+ onChange: (v)=>{
114955
+ setSelectedAgents(v);
114956
+ if (isServerPagination && onFiltersChange) {
114957
+ onFiltersChange(v, selectedMetricFilter);
114958
+ }
114959
+ },
114299
114960
  style: {
114300
114961
  width: 200
114301
114962
  },
@@ -114307,7 +114968,13 @@ const EvaluationsTable = ({ evaluations, loading = false, error = null, onRefres
114307
114968
  placeholder: "Filter by Evaluator / Metric",
114308
114969
  allowClear: true,
114309
114970
  value: selectedMetricFilter ?? undefined,
114310
- onChange: (v)=>setSelectedMetricFilter(v ?? null),
114971
+ onChange: (v)=>{
114972
+ const next = v ?? null;
114973
+ setSelectedMetricFilter(next);
114974
+ if (isServerPagination && onFiltersChange) {
114975
+ onFiltersChange(selectedAgents, next);
114976
+ }
114977
+ },
114311
114978
  style: {
114312
114979
  width: 240
114313
114980
  },
@@ -114330,7 +114997,7 @@ const EvaluationsTable = ({ evaluations, loading = false, error = null, onRefres
114330
114997
  }
114331
114998
  }, emptyMessage ?? defaultEmptyMessage) : /*#__PURE__*/ React__default.createElement(ForwardTable, {
114332
114999
  columns: columns,
114333
- dataSource: filteredEvaluations,
115000
+ dataSource: tableDataSource,
114334
115001
  loading: loading,
114335
115002
  rowKey: "evaluation_id",
114336
115003
  rowSelection: showCompare ? {
@@ -114341,7 +115008,20 @@ const EvaluationsTable = ({ evaluations, loading = false, error = null, onRefres
114341
115008
  disabled: selectedRowKeys.length >= 2 && !selectedRowKeys.includes(record.evaluation_id)
114342
115009
  })
114343
115010
  } : undefined,
114344
- pagination: filteredEvaluations.length <= pageSize ? false : {
115011
+ pagination: isServerPagination && serverPagination ? {
115012
+ total: serverPagination.total,
115013
+ current: serverPagination.current,
115014
+ pageSize: serverPagination.pageSize,
115015
+ showSizeChanger: true,
115016
+ showTotal: (total)=>`Total ${total} evaluations`,
115017
+ pageSizeOptions: [
115018
+ "10",
115019
+ "20",
115020
+ "50",
115021
+ "100"
115022
+ ],
115023
+ onChange: (page, size)=>serverPagination.onPageChange(page, size ?? serverPagination.pageSize)
115024
+ } : tableDataSource.length <= pageSize ? false : {
114345
115025
  pageSize,
114346
115026
  showSizeChanger: true,
114347
115027
  showTotal: (total)=>`Total ${total} evaluations`,
@@ -114372,14 +115052,14 @@ const EvaluationsTable = ({ evaluations, loading = false, error = null, onRefres
114372
115052
  cursor: "pointer"
114373
115053
  }
114374
115054
  })
114375
- }), !onCompare && /*#__PURE__*/ React__default.createElement(EvaluationsCompare, {
115055
+ }), compareDrawerOpen && /*#__PURE__*/ React__default.createElement(EvaluationsCompareDrawer, {
114376
115056
  open: compareDrawerOpen,
114377
115057
  onClose: handleDrawerClose,
114378
- sourceEvaluationId: sourceEvaluationId,
114379
- targetEvaluationId: targetEvaluationId,
114380
- evaluations: normalized,
114381
- onSourceChange: setSourceEvaluationId,
114382
- onTargetChange: setTargetEvaluationId
115058
+ evaluationId1: evaluationId1,
115059
+ evaluationId2: evaluationId2,
115060
+ evaluations: compareDrawerEvaluations,
115061
+ onEvaluationId1Change: onCompareUrlChange ? handleEvaluationId1Change : setEvaluationId1,
115062
+ onEvaluationId2Change: onCompareUrlChange ? handleEvaluationId2Change : setEvaluationId2
114383
115063
  }), !onRowClick && /*#__PURE__*/ React__default.createElement(EvaluationDetailsDrawer, {
114384
115064
  evaluation: selectedEvaluation,
114385
115065
  open: detailsDrawerOpen,
@@ -114387,6 +115067,1938 @@ const EvaluationsTable = ({ evaluations, loading = false, error = null, onRefres
114387
115067
  }));
114388
115068
  };
114389
115069
 
115070
+ function invariant(value, message) {
115071
+ if (value === false || value === null || typeof value === "undefined") {
115072
+ throw new Error(message);
115073
+ }
115074
+ }
115075
+ function warning(cond, message) {
115076
+ if (!cond) {
115077
+ if (typeof console !== "undefined") console.warn(message);
115078
+ try {
115079
+ throw new Error(message);
115080
+ } catch (e) {}
115081
+ }
115082
+ }
115083
+ function createPath({ pathname = "/", search = "", hash = "" }) {
115084
+ if (search && search !== "?") pathname += search.charAt(0) === "?" ? search : "?" + search;
115085
+ if (hash && hash !== "#") pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
115086
+ return pathname;
115087
+ }
115088
+ function parsePath(path) {
115089
+ let parsedPath = {};
115090
+ if (path) {
115091
+ let hashIndex = path.indexOf("#");
115092
+ if (hashIndex >= 0) {
115093
+ parsedPath.hash = path.substring(hashIndex);
115094
+ path = path.substring(0, hashIndex);
115095
+ }
115096
+ let searchIndex = path.indexOf("?");
115097
+ if (searchIndex >= 0) {
115098
+ parsedPath.search = path.substring(searchIndex);
115099
+ path = path.substring(0, searchIndex);
115100
+ }
115101
+ if (path) {
115102
+ parsedPath.pathname = path;
115103
+ }
115104
+ }
115105
+ return parsedPath;
115106
+ }
115107
+ function matchRoutes(routes, locationArg, basename = "/") {
115108
+ return matchRoutesImpl(routes, locationArg, basename, false);
115109
+ }
115110
+ function matchRoutesImpl(routes, locationArg, basename, allowPartial) {
115111
+ let location = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
115112
+ let pathname = stripBasename(location.pathname || "/", basename);
115113
+ if (pathname == null) {
115114
+ return null;
115115
+ }
115116
+ let branches = flattenRoutes(routes);
115117
+ rankRouteBranches(branches);
115118
+ let matches = null;
115119
+ for(let i = 0; matches == null && i < branches.length; ++i){
115120
+ let decoded = decodePath(pathname);
115121
+ matches = matchRouteBranch(branches[i], decoded, allowPartial);
115122
+ }
115123
+ return matches;
115124
+ }
115125
+ function flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = "", _hasParentOptionalSegments = false) {
115126
+ let flattenRoute = (route, index, hasParentOptionalSegments = _hasParentOptionalSegments, relativePath)=>{
115127
+ let meta = {
115128
+ relativePath: relativePath === void 0 ? route.path || "" : relativePath,
115129
+ caseSensitive: route.caseSensitive === true,
115130
+ childrenIndex: index,
115131
+ route
115132
+ };
115133
+ if (meta.relativePath.startsWith("/")) {
115134
+ if (!meta.relativePath.startsWith(parentPath) && hasParentOptionalSegments) {
115135
+ return;
115136
+ }
115137
+ invariant(meta.relativePath.startsWith(parentPath), `Absolute route path "${meta.relativePath}" nested under path "${parentPath}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`);
115138
+ meta.relativePath = meta.relativePath.slice(parentPath.length);
115139
+ }
115140
+ let path = joinPaths([
115141
+ parentPath,
115142
+ meta.relativePath
115143
+ ]);
115144
+ let routesMeta = parentsMeta.concat(meta);
115145
+ if (route.children && route.children.length > 0) {
115146
+ invariant(// Our types know better, but runtime JS may not!
115147
+ // @ts-expect-error
115148
+ route.index !== true, `Index routes must not have child routes. Please remove all child routes from route path "${path}".`);
115149
+ flattenRoutes(route.children, branches, routesMeta, path, hasParentOptionalSegments);
115150
+ }
115151
+ if (route.path == null && !route.index) {
115152
+ return;
115153
+ }
115154
+ branches.push({
115155
+ path,
115156
+ score: computeScore(path, route.index),
115157
+ routesMeta
115158
+ });
115159
+ };
115160
+ routes.forEach((route, index)=>{
115161
+ if (route.path === "" || !route.path?.includes("?")) {
115162
+ flattenRoute(route, index);
115163
+ } else {
115164
+ for (let exploded of explodeOptionalSegments(route.path)){
115165
+ flattenRoute(route, index, true, exploded);
115166
+ }
115167
+ }
115168
+ });
115169
+ return branches;
115170
+ }
115171
+ function explodeOptionalSegments(path) {
115172
+ let segments = path.split("/");
115173
+ if (segments.length === 0) return [];
115174
+ let [first, ...rest] = segments;
115175
+ let isOptional = first.endsWith("?");
115176
+ let required = first.replace(/\?$/, "");
115177
+ if (rest.length === 0) {
115178
+ return isOptional ? [
115179
+ required,
115180
+ ""
115181
+ ] : [
115182
+ required
115183
+ ];
115184
+ }
115185
+ let restExploded = explodeOptionalSegments(rest.join("/"));
115186
+ let result = [];
115187
+ result.push(...restExploded.map((subpath)=>subpath === "" ? required : [
115188
+ required,
115189
+ subpath
115190
+ ].join("/")));
115191
+ if (isOptional) {
115192
+ result.push(...restExploded);
115193
+ }
115194
+ return result.map((exploded)=>path.startsWith("/") && exploded === "" ? "/" : exploded);
115195
+ }
115196
+ function rankRouteBranches(branches) {
115197
+ branches.sort((a, b)=>a.score !== b.score ? b.score - a.score : compareIndexes(a.routesMeta.map((meta)=>meta.childrenIndex), b.routesMeta.map((meta)=>meta.childrenIndex)));
115198
+ }
115199
+ var paramRe = /^:[\w-]+$/;
115200
+ var dynamicSegmentValue = 3;
115201
+ var indexRouteValue = 2;
115202
+ var emptySegmentValue = 1;
115203
+ var staticSegmentValue = 10;
115204
+ var splatPenalty = -2;
115205
+ var isSplat = (s)=>s === "*";
115206
+ function computeScore(path, index) {
115207
+ let segments = path.split("/");
115208
+ let initialScore = segments.length;
115209
+ if (segments.some(isSplat)) {
115210
+ initialScore += splatPenalty;
115211
+ }
115212
+ if (index) {
115213
+ initialScore += indexRouteValue;
115214
+ }
115215
+ return segments.filter((s)=>!isSplat(s)).reduce((score, segment)=>score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), initialScore);
115216
+ }
115217
+ function compareIndexes(a, b) {
115218
+ let siblings = a.length === b.length && a.slice(0, -1).every((n, i)=>n === b[i]);
115219
+ return siblings ? // If two routes are siblings, we should try to match the earlier sibling
115220
+ // first. This allows people to have fine-grained control over the matching
115221
+ // behavior by simply putting routes with identical paths in the order they
115222
+ // want them tried.
115223
+ a[a.length - 1] - b[b.length - 1] : // Otherwise, it doesn't really make sense to rank non-siblings by index,
115224
+ // so they sort equally.
115225
+ 0;
115226
+ }
115227
+ function matchRouteBranch(branch, pathname, allowPartial = false) {
115228
+ let { routesMeta } = branch;
115229
+ let matchedParams = {};
115230
+ let matchedPathname = "/";
115231
+ let matches = [];
115232
+ for(let i = 0; i < routesMeta.length; ++i){
115233
+ let meta = routesMeta[i];
115234
+ let end = i === routesMeta.length - 1;
115235
+ let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
115236
+ let match = matchPath({
115237
+ path: meta.relativePath,
115238
+ caseSensitive: meta.caseSensitive,
115239
+ end
115240
+ }, remainingPathname);
115241
+ let route = meta.route;
115242
+ if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) {
115243
+ match = matchPath({
115244
+ path: meta.relativePath,
115245
+ caseSensitive: meta.caseSensitive,
115246
+ end: false
115247
+ }, remainingPathname);
115248
+ }
115249
+ if (!match) {
115250
+ return null;
115251
+ }
115252
+ Object.assign(matchedParams, match.params);
115253
+ matches.push({
115254
+ // TODO: Can this as be avoided?
115255
+ params: matchedParams,
115256
+ pathname: joinPaths([
115257
+ matchedPathname,
115258
+ match.pathname
115259
+ ]),
115260
+ pathnameBase: normalizePathname(joinPaths([
115261
+ matchedPathname,
115262
+ match.pathnameBase
115263
+ ])),
115264
+ route
115265
+ });
115266
+ if (match.pathnameBase !== "/") {
115267
+ matchedPathname = joinPaths([
115268
+ matchedPathname,
115269
+ match.pathnameBase
115270
+ ]);
115271
+ }
115272
+ }
115273
+ return matches;
115274
+ }
115275
+ function matchPath(pattern, pathname) {
115276
+ if (typeof pattern === "string") {
115277
+ pattern = {
115278
+ path: pattern,
115279
+ caseSensitive: false,
115280
+ end: true
115281
+ };
115282
+ }
115283
+ let [matcher, compiledParams] = compilePath(pattern.path, pattern.caseSensitive, pattern.end);
115284
+ let match = pathname.match(matcher);
115285
+ if (!match) return null;
115286
+ let matchedPathname = match[0];
115287
+ let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
115288
+ let captureGroups = match.slice(1);
115289
+ let params = compiledParams.reduce((memo2, { paramName, isOptional }, index)=>{
115290
+ if (paramName === "*") {
115291
+ let splatValue = captureGroups[index] || "";
115292
+ pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
115293
+ }
115294
+ const value = captureGroups[index];
115295
+ if (isOptional && !value) {
115296
+ memo2[paramName] = void 0;
115297
+ } else {
115298
+ memo2[paramName] = (value || "").replace(/%2F/g, "/");
115299
+ }
115300
+ return memo2;
115301
+ }, {});
115302
+ return {
115303
+ params,
115304
+ pathname: matchedPathname,
115305
+ pathnameBase,
115306
+ pattern
115307
+ };
115308
+ }
115309
+ function compilePath(path, caseSensitive = false, end = true) {
115310
+ warning(path === "*" || !path.endsWith("*") || path.endsWith("/*"), `Route path "${path}" will be treated as if it were "${path.replace(/\*$/, "/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${path.replace(/\*$/, "/*")}".`);
115311
+ let params = [];
115312
+ let regexpSource = "^" + path.replace(/\/*\*?$/, "").replace(/^\/*/, "/").replace(/[\\.*+^${}|()[\]]/g, "\\$&").replace(/\/:([\w-]+)(\?)?/g, (match, paramName, isOptional, index, str)=>{
115313
+ params.push({
115314
+ paramName,
115315
+ isOptional: isOptional != null
115316
+ });
115317
+ if (isOptional) {
115318
+ let nextChar = str.charAt(index + match.length);
115319
+ if (nextChar && nextChar !== "/") {
115320
+ return "/([^\\/]*)";
115321
+ }
115322
+ return "(?:/([^\\/]*))?";
115323
+ }
115324
+ return "/([^\\/]+)";
115325
+ }).replace(/\/([\w-]+)\?(\/|$)/g, "(/$1)?$2");
115326
+ if (path.endsWith("*")) {
115327
+ params.push({
115328
+ paramName: "*"
115329
+ });
115330
+ regexpSource += path === "*" || path === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$";
115331
+ } else if (end) {
115332
+ regexpSource += "\\/*$";
115333
+ } else if (path !== "" && path !== "/") {
115334
+ regexpSource += "(?:(?=\\/|$))";
115335
+ } else ;
115336
+ let matcher = new RegExp(regexpSource, caseSensitive ? void 0 : "i");
115337
+ return [
115338
+ matcher,
115339
+ params
115340
+ ];
115341
+ }
115342
+ function decodePath(value) {
115343
+ try {
115344
+ return value.split("/").map((v)=>decodeURIComponent(v).replace(/\//g, "%2F")).join("/");
115345
+ } catch (error) {
115346
+ warning(false, `The URL path "${value}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${error}).`);
115347
+ return value;
115348
+ }
115349
+ }
115350
+ function stripBasename(pathname, basename) {
115351
+ if (basename === "/") return pathname;
115352
+ if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
115353
+ return null;
115354
+ }
115355
+ let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length;
115356
+ let nextChar = pathname.charAt(startIndex);
115357
+ if (nextChar && nextChar !== "/") {
115358
+ return null;
115359
+ }
115360
+ return pathname.slice(startIndex) || "/";
115361
+ }
115362
+ var ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
115363
+ function resolvePath(to, fromPathname = "/") {
115364
+ let { pathname: toPathname, search = "", hash = "" } = typeof to === "string" ? parsePath(to) : to;
115365
+ let pathname;
115366
+ if (toPathname) {
115367
+ toPathname = toPathname.replace(/\/\/+/g, "/");
115368
+ if (toPathname.startsWith("/")) {
115369
+ pathname = resolvePathname(toPathname.substring(1), "/");
115370
+ } else {
115371
+ pathname = resolvePathname(toPathname, fromPathname);
115372
+ }
115373
+ } else {
115374
+ pathname = fromPathname;
115375
+ }
115376
+ return {
115377
+ pathname,
115378
+ search: normalizeSearch(search),
115379
+ hash: normalizeHash(hash)
115380
+ };
115381
+ }
115382
+ function resolvePathname(relativePath, fromPathname) {
115383
+ let segments = fromPathname.replace(/\/+$/, "").split("/");
115384
+ let relativeSegments = relativePath.split("/");
115385
+ relativeSegments.forEach((segment)=>{
115386
+ if (segment === "..") {
115387
+ if (segments.length > 1) segments.pop();
115388
+ } else if (segment !== ".") {
115389
+ segments.push(segment);
115390
+ }
115391
+ });
115392
+ return segments.length > 1 ? segments.join("/") : "/";
115393
+ }
115394
+ function getInvalidPathError(char, field, dest, path) {
115395
+ return `Cannot include a '${char}' character in a manually specified \`to.${field}\` field [${JSON.stringify(path)}]. Please separate it out to the \`to.${dest}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`;
115396
+ }
115397
+ function getPathContributingMatches(matches) {
115398
+ return matches.filter((match, index)=>index === 0 || match.route.path && match.route.path.length > 0);
115399
+ }
115400
+ function getResolveToMatches(matches) {
115401
+ let pathMatches = getPathContributingMatches(matches);
115402
+ return pathMatches.map((match, idx)=>idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase);
115403
+ }
115404
+ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = false) {
115405
+ let to;
115406
+ if (typeof toArg === "string") {
115407
+ to = parsePath(toArg);
115408
+ } else {
115409
+ to = {
115410
+ ...toArg
115411
+ };
115412
+ invariant(!to.pathname || !to.pathname.includes("?"), getInvalidPathError("?", "pathname", "search", to));
115413
+ invariant(!to.pathname || !to.pathname.includes("#"), getInvalidPathError("#", "pathname", "hash", to));
115414
+ invariant(!to.search || !to.search.includes("#"), getInvalidPathError("#", "search", "hash", to));
115415
+ }
115416
+ let isEmptyPath = toArg === "" || to.pathname === "";
115417
+ let toPathname = isEmptyPath ? "/" : to.pathname;
115418
+ let from;
115419
+ if (toPathname == null) {
115420
+ from = locationPathname;
115421
+ } else {
115422
+ let routePathnameIndex = routePathnames.length - 1;
115423
+ if (!isPathRelative && toPathname.startsWith("..")) {
115424
+ let toSegments = toPathname.split("/");
115425
+ while(toSegments[0] === ".."){
115426
+ toSegments.shift();
115427
+ routePathnameIndex -= 1;
115428
+ }
115429
+ to.pathname = toSegments.join("/");
115430
+ }
115431
+ from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
115432
+ }
115433
+ let path = resolvePath(to, from);
115434
+ let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/");
115435
+ let hasCurrentTrailingSlash = (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/");
115436
+ if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) {
115437
+ path.pathname += "/";
115438
+ }
115439
+ return path;
115440
+ }
115441
+ var joinPaths = (paths)=>paths.join("/").replace(/\/\/+/g, "/");
115442
+ var normalizePathname = (pathname)=>pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
115443
+ var normalizeSearch = (search)=>!search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
115444
+ var normalizeHash = (hash)=>!hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
115445
+ var ErrorResponseImpl = class {
115446
+ constructor(status, statusText, data2, internal = false){
115447
+ this.status = status;
115448
+ this.statusText = statusText || "";
115449
+ this.internal = internal;
115450
+ if (data2 instanceof Error) {
115451
+ this.data = data2.toString();
115452
+ this.error = data2;
115453
+ } else {
115454
+ this.data = data2;
115455
+ }
115456
+ }
115457
+ };
115458
+ function isRouteErrorResponse(error) {
115459
+ return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error;
115460
+ }
115461
+ function getRoutePattern(matches) {
115462
+ return matches.map((m)=>m.route.path).filter(Boolean).join("/").replace(/\/\/*/g, "/") || "/";
115463
+ }
115464
+ var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
115465
+ function parseToInfo(_to, basename) {
115466
+ let to = _to;
115467
+ if (typeof to !== "string" || !ABSOLUTE_URL_REGEX.test(to)) {
115468
+ return {
115469
+ absoluteURL: void 0,
115470
+ isExternal: false,
115471
+ to
115472
+ };
115473
+ }
115474
+ let absoluteURL = to;
115475
+ let isExternal = false;
115476
+ if (isBrowser) {
115477
+ try {
115478
+ let currentUrl = new URL(window.location.href);
115479
+ let targetUrl = to.startsWith("//") ? new URL(currentUrl.protocol + to) : new URL(to);
115480
+ let path = stripBasename(targetUrl.pathname, basename);
115481
+ if (targetUrl.origin === currentUrl.origin && path != null) {
115482
+ to = path + targetUrl.search + targetUrl.hash;
115483
+ } else {
115484
+ isExternal = true;
115485
+ }
115486
+ } catch (e) {
115487
+ warning(false, `<Link to="${to}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`);
115488
+ }
115489
+ }
115490
+ return {
115491
+ absoluteURL,
115492
+ isExternal,
115493
+ to
115494
+ };
115495
+ }
115496
+ Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
115497
+ // lib/router/router.ts
115498
+ var validMutationMethodsArr = [
115499
+ "POST",
115500
+ "PUT",
115501
+ "PATCH",
115502
+ "DELETE"
115503
+ ];
115504
+ new Set(validMutationMethodsArr);
115505
+ var validRequestMethodsArr = [
115506
+ "GET",
115507
+ ...validMutationMethodsArr
115508
+ ];
115509
+ new Set(validRequestMethodsArr);
115510
+ var DataRouterContext = React.createContext(null);
115511
+ DataRouterContext.displayName = "DataRouter";
115512
+ var DataRouterStateContext = React.createContext(null);
115513
+ DataRouterStateContext.displayName = "DataRouterState";
115514
+ var RSCRouterContext = React.createContext(false);
115515
+ var ViewTransitionContext = React.createContext({
115516
+ isTransitioning: false
115517
+ });
115518
+ ViewTransitionContext.displayName = "ViewTransition";
115519
+ var FetchersContext = React.createContext(/* @__PURE__ */ new Map());
115520
+ FetchersContext.displayName = "Fetchers";
115521
+ var AwaitContext = React.createContext(null);
115522
+ AwaitContext.displayName = "Await";
115523
+ var NavigationContext = React.createContext(null);
115524
+ NavigationContext.displayName = "Navigation";
115525
+ var LocationContext = React.createContext(null);
115526
+ LocationContext.displayName = "Location";
115527
+ var RouteContext = React.createContext({
115528
+ outlet: null,
115529
+ matches: [],
115530
+ isDataRoute: false
115531
+ });
115532
+ RouteContext.displayName = "Route";
115533
+ var RouteErrorContext = React.createContext(null);
115534
+ RouteErrorContext.displayName = "RouteError";
115535
+ // lib/errors.ts
115536
+ var ERROR_DIGEST_BASE = "REACT_ROUTER_ERROR";
115537
+ var ERROR_DIGEST_REDIRECT = "REDIRECT";
115538
+ var ERROR_DIGEST_ROUTE_ERROR_RESPONSE = "ROUTE_ERROR_RESPONSE";
115539
+ function decodeRedirectErrorDigest(digest) {
115540
+ if (digest.startsWith(`${ERROR_DIGEST_BASE}:${ERROR_DIGEST_REDIRECT}:{`)) {
115541
+ try {
115542
+ let parsed = JSON.parse(digest.slice(28));
115543
+ if (typeof parsed === "object" && parsed && typeof parsed.status === "number" && typeof parsed.statusText === "string" && typeof parsed.location === "string" && typeof parsed.reloadDocument === "boolean" && typeof parsed.replace === "boolean") {
115544
+ return parsed;
115545
+ }
115546
+ } catch {}
115547
+ }
115548
+ }
115549
+ function decodeRouteErrorResponseDigest(digest) {
115550
+ if (digest.startsWith(`${ERROR_DIGEST_BASE}:${ERROR_DIGEST_ROUTE_ERROR_RESPONSE}:{`)) {
115551
+ try {
115552
+ let parsed = JSON.parse(digest.slice(40));
115553
+ if (typeof parsed === "object" && parsed && typeof parsed.status === "number" && typeof parsed.statusText === "string") {
115554
+ return new ErrorResponseImpl(parsed.status, parsed.statusText, parsed.data);
115555
+ }
115556
+ } catch {}
115557
+ }
115558
+ }
115559
+ // lib/hooks.tsx
115560
+ function useHref(to, { relative } = {}) {
115561
+ invariant(useInRouterContext(), // TODO: This error is probably because they somehow have 2 versions of the
115562
+ // router loaded. We can help them understand how to avoid that.
115563
+ `useHref() may be used only in the context of a <Router> component.`);
115564
+ let { basename, navigator } = React.useContext(NavigationContext);
115565
+ let { hash, pathname, search } = useResolvedPath(to, {
115566
+ relative
115567
+ });
115568
+ let joinedPathname = pathname;
115569
+ if (basename !== "/") {
115570
+ joinedPathname = pathname === "/" ? basename : joinPaths([
115571
+ basename,
115572
+ pathname
115573
+ ]);
115574
+ }
115575
+ return navigator.createHref({
115576
+ pathname: joinedPathname,
115577
+ search,
115578
+ hash
115579
+ });
115580
+ }
115581
+ function useInRouterContext() {
115582
+ return React.useContext(LocationContext) != null;
115583
+ }
115584
+ function useLocation() {
115585
+ invariant(useInRouterContext(), // TODO: This error is probably because they somehow have 2 versions of the
115586
+ // router loaded. We can help them understand how to avoid that.
115587
+ `useLocation() may be used only in the context of a <Router> component.`);
115588
+ return React.useContext(LocationContext).location;
115589
+ }
115590
+ var navigateEffectWarning = `You should call navigate() in a React.useEffect(), not when your component is first rendered.`;
115591
+ function useIsomorphicLayoutEffect$1(cb) {
115592
+ let isStatic = React.useContext(NavigationContext).static;
115593
+ if (!isStatic) {
115594
+ React.useLayoutEffect(cb);
115595
+ }
115596
+ }
115597
+ function useNavigate() {
115598
+ let { isDataRoute } = React.useContext(RouteContext);
115599
+ return isDataRoute ? useNavigateStable() : useNavigateUnstable();
115600
+ }
115601
+ function useNavigateUnstable() {
115602
+ invariant(useInRouterContext(), // TODO: This error is probably because they somehow have 2 versions of the
115603
+ // router loaded. We can help them understand how to avoid that.
115604
+ `useNavigate() may be used only in the context of a <Router> component.`);
115605
+ let dataRouterContext = React.useContext(DataRouterContext);
115606
+ let { basename, navigator } = React.useContext(NavigationContext);
115607
+ let { matches } = React.useContext(RouteContext);
115608
+ let { pathname: locationPathname } = useLocation();
115609
+ let routePathnamesJson = JSON.stringify(getResolveToMatches(matches));
115610
+ let activeRef = React.useRef(false);
115611
+ useIsomorphicLayoutEffect$1(()=>{
115612
+ activeRef.current = true;
115613
+ });
115614
+ let navigate = React.useCallback((to, options = {})=>{
115615
+ warning(activeRef.current, navigateEffectWarning);
115616
+ if (!activeRef.current) return;
115617
+ if (typeof to === "number") {
115618
+ navigator.go(to);
115619
+ return;
115620
+ }
115621
+ let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === "path");
115622
+ if (dataRouterContext == null && basename !== "/") {
115623
+ path.pathname = path.pathname === "/" ? basename : joinPaths([
115624
+ basename,
115625
+ path.pathname
115626
+ ]);
115627
+ }
115628
+ (!!options.replace ? navigator.replace : navigator.push)(path, options.state, options);
115629
+ }, [
115630
+ basename,
115631
+ navigator,
115632
+ routePathnamesJson,
115633
+ locationPathname,
115634
+ dataRouterContext
115635
+ ]);
115636
+ return navigate;
115637
+ }
115638
+ React.createContext(null);
115639
+ function useResolvedPath(to, { relative } = {}) {
115640
+ let { matches } = React.useContext(RouteContext);
115641
+ let { pathname: locationPathname } = useLocation();
115642
+ let routePathnamesJson = JSON.stringify(getResolveToMatches(matches));
115643
+ return React.useMemo(()=>resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === "path"), [
115644
+ to,
115645
+ routePathnamesJson,
115646
+ locationPathname,
115647
+ relative
115648
+ ]);
115649
+ }
115650
+ function useRoutesImpl(routes, locationArg, dataRouterOpts) {
115651
+ invariant(useInRouterContext(), // TODO: This error is probably because they somehow have 2 versions of the
115652
+ // router loaded. We can help them understand how to avoid that.
115653
+ `useRoutes() may be used only in the context of a <Router> component.`);
115654
+ let { navigator } = React.useContext(NavigationContext);
115655
+ let { matches: parentMatches } = React.useContext(RouteContext);
115656
+ let routeMatch = parentMatches[parentMatches.length - 1];
115657
+ let parentParams = routeMatch ? routeMatch.params : {};
115658
+ let parentPathname = routeMatch ? routeMatch.pathname : "/";
115659
+ let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/";
115660
+ let parentRoute = routeMatch && routeMatch.route;
115661
+ {
115662
+ let parentPath = parentRoute && parentRoute.path || "";
115663
+ warningOnce(parentPathname, !parentRoute || parentPath.endsWith("*") || parentPath.endsWith("*?"), `You rendered descendant <Routes> (or called \`useRoutes()\`) at "${parentPathname}" (under <Route path="${parentPath}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
115664
+
115665
+ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPath === "/" ? "*" : `${parentPath}/*`}">.`);
115666
+ }
115667
+ let locationFromContext = useLocation();
115668
+ let location;
115669
+ {
115670
+ location = locationFromContext;
115671
+ }
115672
+ let pathname = location.pathname || "/";
115673
+ let remainingPathname = pathname;
115674
+ if (parentPathnameBase !== "/") {
115675
+ let parentSegments = parentPathnameBase.replace(/^\//, "").split("/");
115676
+ let segments = pathname.replace(/^\//, "").split("/");
115677
+ remainingPathname = "/" + segments.slice(parentSegments.length).join("/");
115678
+ }
115679
+ let matches = matchRoutes(routes, {
115680
+ pathname: remainingPathname
115681
+ });
115682
+ {
115683
+ warning(parentRoute || matches != null, `No routes matched location "${location.pathname}${location.search}${location.hash}" `);
115684
+ warning(matches == null || matches[matches.length - 1].route.element !== void 0 || matches[matches.length - 1].route.Component !== void 0 || matches[matches.length - 1].route.lazy !== void 0, `Matched leaf route at location "${location.pathname}${location.search}${location.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);
115685
+ }
115686
+ let renderedMatches = _renderMatches(matches && matches.map((match)=>Object.assign({}, match, {
115687
+ params: Object.assign({}, parentParams, match.params),
115688
+ pathname: joinPaths([
115689
+ parentPathnameBase,
115690
+ // Re-encode pathnames that were decoded inside matchRoutes.
115691
+ // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses
115692
+ // `new URL()` internally and we need to prevent it from treating
115693
+ // them as separators
115694
+ navigator.encodeLocation ? navigator.encodeLocation(match.pathname.replace(/\?/g, "%3F").replace(/#/g, "%23")).pathname : match.pathname
115695
+ ]),
115696
+ pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([
115697
+ parentPathnameBase,
115698
+ // Re-encode pathnames that were decoded inside matchRoutes
115699
+ // Pre-encode `?` and `#` ahead of `encodeLocation` because it uses
115700
+ // `new URL()` internally and we need to prevent it from treating
115701
+ // them as separators
115702
+ navigator.encodeLocation ? navigator.encodeLocation(match.pathnameBase.replace(/\?/g, "%3F").replace(/#/g, "%23")).pathname : match.pathnameBase
115703
+ ])
115704
+ })), parentMatches, dataRouterOpts);
115705
+ return renderedMatches;
115706
+ }
115707
+ function DefaultErrorComponent() {
115708
+ let error = useRouteError();
115709
+ let message = isRouteErrorResponse(error) ? `${error.status} ${error.statusText}` : error instanceof Error ? error.message : JSON.stringify(error);
115710
+ let stack = error instanceof Error ? error.stack : null;
115711
+ let lightgrey = "rgba(200,200,200, 0.5)";
115712
+ let preStyles = {
115713
+ padding: "0.5rem",
115714
+ backgroundColor: lightgrey
115715
+ };
115716
+ let codeStyles = {
115717
+ padding: "2px 4px",
115718
+ backgroundColor: lightgrey
115719
+ };
115720
+ let devInfo = null;
115721
+ {
115722
+ console.error("Error handled by React Router default ErrorBoundary:", error);
115723
+ devInfo = /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("p", null, "\u{1F4BF} Hey developer \u{1F44B}"), /* @__PURE__ */ React.createElement("p", null, "You can provide a way better UX than this when your app throws errors by providing your own ", /* @__PURE__ */ React.createElement("code", {
115724
+ style: codeStyles
115725
+ }, "ErrorBoundary"), " or", " ", /* @__PURE__ */ React.createElement("code", {
115726
+ style: codeStyles
115727
+ }, "errorElement"), " prop on your route."));
115728
+ }
115729
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h2", null, "Unexpected Application Error!"), /* @__PURE__ */ React.createElement("h3", {
115730
+ style: {
115731
+ fontStyle: "italic"
115732
+ }
115733
+ }, message), stack ? /* @__PURE__ */ React.createElement("pre", {
115734
+ style: preStyles
115735
+ }, stack) : null, devInfo);
115736
+ }
115737
+ var defaultErrorElement = /* @__PURE__ */ React.createElement(DefaultErrorComponent, null);
115738
+ var RenderErrorBoundary = class extends React.Component {
115739
+ static getDerivedStateFromError(error) {
115740
+ return {
115741
+ error
115742
+ };
115743
+ }
115744
+ static getDerivedStateFromProps(props, state) {
115745
+ if (state.location !== props.location || state.revalidation !== "idle" && props.revalidation === "idle") {
115746
+ return {
115747
+ error: props.error,
115748
+ location: props.location,
115749
+ revalidation: props.revalidation
115750
+ };
115751
+ }
115752
+ return {
115753
+ error: props.error !== void 0 ? props.error : state.error,
115754
+ location: state.location,
115755
+ revalidation: props.revalidation || state.revalidation
115756
+ };
115757
+ }
115758
+ componentDidCatch(error, errorInfo) {
115759
+ if (this.props.onError) {
115760
+ this.props.onError(error, errorInfo);
115761
+ } else {
115762
+ console.error("React Router caught the following error during render", error);
115763
+ }
115764
+ }
115765
+ render() {
115766
+ let error = this.state.error;
115767
+ if (this.context && typeof error === "object" && error && "digest" in error && typeof error.digest === "string") {
115768
+ const decoded = decodeRouteErrorResponseDigest(error.digest);
115769
+ if (decoded) error = decoded;
115770
+ }
115771
+ let result = error !== void 0 ? /* @__PURE__ */ React.createElement(RouteContext.Provider, {
115772
+ value: this.props.routeContext
115773
+ }, /* @__PURE__ */ React.createElement(RouteErrorContext.Provider, {
115774
+ value: error,
115775
+ children: this.props.component
115776
+ })) : this.props.children;
115777
+ if (this.context) {
115778
+ return /* @__PURE__ */ React.createElement(RSCErrorHandler, {
115779
+ error
115780
+ }, result);
115781
+ }
115782
+ return result;
115783
+ }
115784
+ constructor(props){
115785
+ super(props);
115786
+ this.state = {
115787
+ location: props.location,
115788
+ revalidation: props.revalidation,
115789
+ error: props.error
115790
+ };
115791
+ }
115792
+ };
115793
+ RenderErrorBoundary.contextType = RSCRouterContext;
115794
+ var errorRedirectHandledMap = /* @__PURE__ */ new WeakMap();
115795
+ function RSCErrorHandler({ children, error }) {
115796
+ let { basename } = React.useContext(NavigationContext);
115797
+ if (typeof error === "object" && error && "digest" in error && typeof error.digest === "string") {
115798
+ let redirect2 = decodeRedirectErrorDigest(error.digest);
115799
+ if (redirect2) {
115800
+ let existingRedirect = errorRedirectHandledMap.get(error);
115801
+ if (existingRedirect) throw existingRedirect;
115802
+ let parsed = parseToInfo(redirect2.location, basename);
115803
+ if (isBrowser && !errorRedirectHandledMap.get(error)) {
115804
+ if (parsed.isExternal || redirect2.reloadDocument) {
115805
+ window.location.href = parsed.absoluteURL || parsed.to;
115806
+ } else {
115807
+ const redirectPromise = Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(parsed.to, {
115808
+ replace: redirect2.replace
115809
+ }));
115810
+ errorRedirectHandledMap.set(error, redirectPromise);
115811
+ throw redirectPromise;
115812
+ }
115813
+ }
115814
+ return /* @__PURE__ */ React.createElement("meta", {
115815
+ httpEquiv: "refresh",
115816
+ content: `0;url=${parsed.absoluteURL || parsed.to}`
115817
+ });
115818
+ }
115819
+ }
115820
+ return children;
115821
+ }
115822
+ function RenderedRoute({ routeContext, match, children }) {
115823
+ let dataRouterContext = React.useContext(DataRouterContext);
115824
+ if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {
115825
+ dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;
115826
+ }
115827
+ return /* @__PURE__ */ React.createElement(RouteContext.Provider, {
115828
+ value: routeContext
115829
+ }, children);
115830
+ }
115831
+ function _renderMatches(matches, parentMatches = [], dataRouterOpts) {
115832
+ let dataRouterState = dataRouterOpts?.state;
115833
+ if (matches == null) {
115834
+ if (!dataRouterState) {
115835
+ return null;
115836
+ }
115837
+ if (dataRouterState.errors) {
115838
+ matches = dataRouterState.matches;
115839
+ } else if (parentMatches.length === 0 && !dataRouterState.initialized && dataRouterState.matches.length > 0) {
115840
+ matches = dataRouterState.matches;
115841
+ } else {
115842
+ return null;
115843
+ }
115844
+ }
115845
+ let renderedMatches = matches;
115846
+ let errors = dataRouterState?.errors;
115847
+ if (errors != null) {
115848
+ let errorIndex = renderedMatches.findIndex((m)=>m.route.id && errors?.[m.route.id] !== void 0);
115849
+ invariant(errorIndex >= 0, `Could not find a matching route for errors on route IDs: ${Object.keys(errors).join(",")}`);
115850
+ renderedMatches = renderedMatches.slice(0, Math.min(renderedMatches.length, errorIndex + 1));
115851
+ }
115852
+ let renderFallback = false;
115853
+ let fallbackIndex = -1;
115854
+ if (dataRouterOpts && dataRouterState) {
115855
+ renderFallback = dataRouterState.renderFallback;
115856
+ for(let i = 0; i < renderedMatches.length; i++){
115857
+ let match = renderedMatches[i];
115858
+ if (match.route.HydrateFallback || match.route.hydrateFallbackElement) {
115859
+ fallbackIndex = i;
115860
+ }
115861
+ if (match.route.id) {
115862
+ let { loaderData, errors: errors2 } = dataRouterState;
115863
+ let needsToRunLoader = match.route.loader && !loaderData.hasOwnProperty(match.route.id) && (!errors2 || errors2[match.route.id] === void 0);
115864
+ if (match.route.lazy || needsToRunLoader) {
115865
+ if (dataRouterOpts.isStatic) {
115866
+ renderFallback = true;
115867
+ }
115868
+ if (fallbackIndex >= 0) {
115869
+ renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);
115870
+ } else {
115871
+ renderedMatches = [
115872
+ renderedMatches[0]
115873
+ ];
115874
+ }
115875
+ break;
115876
+ }
115877
+ }
115878
+ }
115879
+ }
115880
+ let onErrorHandler = dataRouterOpts?.onError;
115881
+ let onError = dataRouterState && onErrorHandler ? (error, errorInfo)=>{
115882
+ onErrorHandler(error, {
115883
+ location: dataRouterState.location,
115884
+ params: dataRouterState.matches?.[0]?.params ?? {},
115885
+ unstable_pattern: getRoutePattern(dataRouterState.matches),
115886
+ errorInfo
115887
+ });
115888
+ } : void 0;
115889
+ return renderedMatches.reduceRight((outlet, match, index)=>{
115890
+ let error;
115891
+ let shouldRenderHydrateFallback = false;
115892
+ let errorElement = null;
115893
+ let hydrateFallbackElement = null;
115894
+ if (dataRouterState) {
115895
+ error = errors && match.route.id ? errors[match.route.id] : void 0;
115896
+ errorElement = match.route.errorElement || defaultErrorElement;
115897
+ if (renderFallback) {
115898
+ if (fallbackIndex < 0 && index === 0) {
115899
+ warningOnce("route-fallback", false, "No `HydrateFallback` element provided to render during initial hydration");
115900
+ shouldRenderHydrateFallback = true;
115901
+ hydrateFallbackElement = null;
115902
+ } else if (fallbackIndex === index) {
115903
+ shouldRenderHydrateFallback = true;
115904
+ hydrateFallbackElement = match.route.hydrateFallbackElement || null;
115905
+ }
115906
+ }
115907
+ }
115908
+ let matches2 = parentMatches.concat(renderedMatches.slice(0, index + 1));
115909
+ let getChildren = ()=>{
115910
+ let children;
115911
+ if (error) {
115912
+ children = errorElement;
115913
+ } else if (shouldRenderHydrateFallback) {
115914
+ children = hydrateFallbackElement;
115915
+ } else if (match.route.Component) {
115916
+ children = /* @__PURE__ */ React.createElement(match.route.Component, null);
115917
+ } else if (match.route.element) {
115918
+ children = match.route.element;
115919
+ } else {
115920
+ children = outlet;
115921
+ }
115922
+ return /* @__PURE__ */ React.createElement(RenderedRoute, {
115923
+ match,
115924
+ routeContext: {
115925
+ outlet,
115926
+ matches: matches2,
115927
+ isDataRoute: dataRouterState != null
115928
+ },
115929
+ children
115930
+ });
115931
+ };
115932
+ return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /* @__PURE__ */ React.createElement(RenderErrorBoundary, {
115933
+ location: dataRouterState.location,
115934
+ revalidation: dataRouterState.revalidation,
115935
+ component: errorElement,
115936
+ error,
115937
+ children: getChildren(),
115938
+ routeContext: {
115939
+ outlet: null,
115940
+ matches: matches2,
115941
+ isDataRoute: true
115942
+ },
115943
+ onError
115944
+ }) : getChildren();
115945
+ }, null);
115946
+ }
115947
+ function getDataRouterConsoleError(hookName) {
115948
+ return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`;
115949
+ }
115950
+ function useDataRouterContext(hookName) {
115951
+ let ctx = React.useContext(DataRouterContext);
115952
+ invariant(ctx, getDataRouterConsoleError(hookName));
115953
+ return ctx;
115954
+ }
115955
+ function useDataRouterState(hookName) {
115956
+ let state = React.useContext(DataRouterStateContext);
115957
+ invariant(state, getDataRouterConsoleError(hookName));
115958
+ return state;
115959
+ }
115960
+ function useRouteContext(hookName) {
115961
+ let route = React.useContext(RouteContext);
115962
+ invariant(route, getDataRouterConsoleError(hookName));
115963
+ return route;
115964
+ }
115965
+ function useCurrentRouteId(hookName) {
115966
+ let route = useRouteContext(hookName);
115967
+ let thisRoute = route.matches[route.matches.length - 1];
115968
+ invariant(thisRoute.route.id, `${hookName} can only be used on routes that contain a unique "id"`);
115969
+ return thisRoute.route.id;
115970
+ }
115971
+ function useRouteId() {
115972
+ return useCurrentRouteId("useRouteId" /* UseRouteId */ );
115973
+ }
115974
+ function useRouteError() {
115975
+ let error = React.useContext(RouteErrorContext);
115976
+ let state = useDataRouterState("useRouteError" /* UseRouteError */ );
115977
+ let routeId = useCurrentRouteId("useRouteError" /* UseRouteError */ );
115978
+ if (error !== void 0) {
115979
+ return error;
115980
+ }
115981
+ return state.errors?.[routeId];
115982
+ }
115983
+ function useNavigateStable() {
115984
+ let { router } = useDataRouterContext("useNavigate" /* UseNavigateStable */ );
115985
+ let id = useCurrentRouteId("useNavigate" /* UseNavigateStable */ );
115986
+ let activeRef = React.useRef(false);
115987
+ useIsomorphicLayoutEffect$1(()=>{
115988
+ activeRef.current = true;
115989
+ });
115990
+ let navigate = React.useCallback(async (to, options = {})=>{
115991
+ warning(activeRef.current, navigateEffectWarning);
115992
+ if (!activeRef.current) return;
115993
+ if (typeof to === "number") {
115994
+ await router.navigate(to);
115995
+ } else {
115996
+ await router.navigate(to, {
115997
+ fromRouteId: id,
115998
+ ...options
115999
+ });
116000
+ }
116001
+ }, [
116002
+ router,
116003
+ id
116004
+ ]);
116005
+ return navigate;
116006
+ }
116007
+ var alreadyWarned = {};
116008
+ function warningOnce(key, cond, message) {
116009
+ if (!cond && !alreadyWarned[key]) {
116010
+ alreadyWarned[key] = true;
116011
+ warning(false, message);
116012
+ }
116013
+ }
116014
+ React.memo(DataRoutes);
116015
+ function DataRoutes({ routes, future, state, isStatic, onError }) {
116016
+ return useRoutesImpl(routes, void 0, {
116017
+ state,
116018
+ isStatic,
116019
+ onError});
116020
+ }
116021
+ // lib/dom/dom.ts
116022
+ var defaultMethod = "get";
116023
+ var defaultEncType = "application/x-www-form-urlencoded";
116024
+ function isHtmlElement(object) {
116025
+ return typeof HTMLElement !== "undefined" && object instanceof HTMLElement;
116026
+ }
116027
+ function isButtonElement(object) {
116028
+ return isHtmlElement(object) && object.tagName.toLowerCase() === "button";
116029
+ }
116030
+ function isFormElement(object) {
116031
+ return isHtmlElement(object) && object.tagName.toLowerCase() === "form";
116032
+ }
116033
+ function isInputElement(object) {
116034
+ return isHtmlElement(object) && object.tagName.toLowerCase() === "input";
116035
+ }
116036
+ function isModifiedEvent(event) {
116037
+ return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
116038
+ }
116039
+ function shouldProcessLinkClick(event, target) {
116040
+ return event.button === 0 && // Ignore everything but left clicks
116041
+ (!target || target === "_self") && // Let browser handle "target=_blank" etc.
116042
+ !isModifiedEvent(event);
116043
+ }
116044
+ function createSearchParams(init = "") {
116045
+ return new URLSearchParams(typeof init === "string" || Array.isArray(init) || init instanceof URLSearchParams ? init : Object.keys(init).reduce((memo2, key)=>{
116046
+ let value = init[key];
116047
+ return memo2.concat(Array.isArray(value) ? value.map((v)=>[
116048
+ key,
116049
+ v
116050
+ ]) : [
116051
+ [
116052
+ key,
116053
+ value
116054
+ ]
116055
+ ]);
116056
+ }, []));
116057
+ }
116058
+ function getSearchParamsForLocation(locationSearch, defaultSearchParams) {
116059
+ let searchParams = createSearchParams(locationSearch);
116060
+ if (defaultSearchParams) {
116061
+ defaultSearchParams.forEach((_, key)=>{
116062
+ if (!searchParams.has(key)) {
116063
+ defaultSearchParams.getAll(key).forEach((value)=>{
116064
+ searchParams.append(key, value);
116065
+ });
116066
+ }
116067
+ });
116068
+ }
116069
+ return searchParams;
116070
+ }
116071
+ var _formDataSupportsSubmitter = null;
116072
+ function isFormDataSubmitterSupported() {
116073
+ if (_formDataSupportsSubmitter === null) {
116074
+ try {
116075
+ new FormData(document.createElement("form"), // @ts-expect-error if FormData supports the submitter parameter, this will throw
116076
+ 0);
116077
+ _formDataSupportsSubmitter = false;
116078
+ } catch (e) {
116079
+ _formDataSupportsSubmitter = true;
116080
+ }
116081
+ }
116082
+ return _formDataSupportsSubmitter;
116083
+ }
116084
+ var supportedFormEncTypes = /* @__PURE__ */ new Set([
116085
+ "application/x-www-form-urlencoded",
116086
+ "multipart/form-data",
116087
+ "text/plain"
116088
+ ]);
116089
+ function getFormEncType(encType) {
116090
+ if (encType != null && !supportedFormEncTypes.has(encType)) {
116091
+ warning(false, `"${encType}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${defaultEncType}"`);
116092
+ return null;
116093
+ }
116094
+ return encType;
116095
+ }
116096
+ function getFormSubmissionInfo(target, basename) {
116097
+ let method;
116098
+ let action;
116099
+ let encType;
116100
+ let formData;
116101
+ let body;
116102
+ if (isFormElement(target)) {
116103
+ let attr = target.getAttribute("action");
116104
+ action = attr ? stripBasename(attr, basename) : null;
116105
+ method = target.getAttribute("method") || defaultMethod;
116106
+ encType = getFormEncType(target.getAttribute("enctype")) || defaultEncType;
116107
+ formData = new FormData(target);
116108
+ } else if (isButtonElement(target) || isInputElement(target) && (target.type === "submit" || target.type === "image")) {
116109
+ let form = target.form;
116110
+ if (form == null) {
116111
+ throw new Error(`Cannot submit a <button> or <input type="submit"> without a <form>`);
116112
+ }
116113
+ let attr = target.getAttribute("formaction") || form.getAttribute("action");
116114
+ action = attr ? stripBasename(attr, basename) : null;
116115
+ method = target.getAttribute("formmethod") || form.getAttribute("method") || defaultMethod;
116116
+ encType = getFormEncType(target.getAttribute("formenctype")) || getFormEncType(form.getAttribute("enctype")) || defaultEncType;
116117
+ formData = new FormData(form, target);
116118
+ if (!isFormDataSubmitterSupported()) {
116119
+ let { name, type, value } = target;
116120
+ if (type === "image") {
116121
+ let prefix = name ? `${name}.` : "";
116122
+ formData.append(`${prefix}x`, "0");
116123
+ formData.append(`${prefix}y`, "0");
116124
+ } else if (name) {
116125
+ formData.append(name, value);
116126
+ }
116127
+ }
116128
+ } else if (isHtmlElement(target)) {
116129
+ throw new Error(`Cannot submit element that is not <form>, <button>, or <input type="submit|image">`);
116130
+ } else {
116131
+ method = defaultMethod;
116132
+ action = null;
116133
+ encType = defaultEncType;
116134
+ body = target;
116135
+ }
116136
+ if (formData && encType === "text/plain") {
116137
+ body = formData;
116138
+ formData = void 0;
116139
+ }
116140
+ return {
116141
+ action,
116142
+ method: method.toLowerCase(),
116143
+ encType,
116144
+ formData,
116145
+ body
116146
+ };
116147
+ }
116148
+ Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
116149
+ // lib/dom/ssr/invariant.ts
116150
+ function invariant2(value, message) {
116151
+ if (value === false || value === null || typeof value === "undefined") {
116152
+ throw new Error(message);
116153
+ }
116154
+ }
116155
+ function singleFetchUrl(reqUrl, basename, trailingSlashAware, extension) {
116156
+ let url = typeof reqUrl === "string" ? new URL(reqUrl, // This can be called during the SSR flow via PrefetchPageLinksImpl so
116157
+ // don't assume window is available
116158
+ typeof window === "undefined" ? "server://singlefetch/" : window.location.origin) : reqUrl;
116159
+ if (trailingSlashAware) {
116160
+ if (url.pathname.endsWith("/")) {
116161
+ url.pathname = `${url.pathname}_.${extension}`;
116162
+ } else {
116163
+ url.pathname = `${url.pathname}.${extension}`;
116164
+ }
116165
+ } else {
116166
+ if (url.pathname === "/") {
116167
+ url.pathname = `_root.${extension}`;
116168
+ } else if (basename && stripBasename(url.pathname, basename) === "/") {
116169
+ url.pathname = `${basename.replace(/\/$/, "")}/_root.${extension}`;
116170
+ } else {
116171
+ url.pathname = `${url.pathname.replace(/\/$/, "")}.${extension}`;
116172
+ }
116173
+ }
116174
+ return url;
116175
+ }
116176
+ // lib/dom/ssr/routeModules.ts
116177
+ async function loadRouteModule(route, routeModulesCache) {
116178
+ if (route.id in routeModulesCache) {
116179
+ return routeModulesCache[route.id];
116180
+ }
116181
+ try {
116182
+ let routeModule = await import(/* @vite-ignore */ /* webpackIgnore: true */ route.module);
116183
+ routeModulesCache[route.id] = routeModule;
116184
+ return routeModule;
116185
+ } catch (error) {
116186
+ console.error(`Error loading route module \`${route.module}\`, reloading page...`);
116187
+ console.error(error);
116188
+ if (window.__reactRouterContext && window.__reactRouterContext.isSpaMode && // @ts-expect-error
116189
+ import.meta.hot) {
116190
+ throw error;
116191
+ }
116192
+ window.location.reload();
116193
+ return new Promise(()=>{});
116194
+ }
116195
+ }
116196
+ function isHtmlLinkDescriptor(object) {
116197
+ if (object == null) {
116198
+ return false;
116199
+ }
116200
+ if (object.href == null) {
116201
+ return object.rel === "preload" && typeof object.imageSrcSet === "string" && typeof object.imageSizes === "string";
116202
+ }
116203
+ return typeof object.rel === "string" && typeof object.href === "string";
116204
+ }
116205
+ async function getKeyedPrefetchLinks(matches, manifest, routeModules) {
116206
+ let links = await Promise.all(matches.map(async (match)=>{
116207
+ let route = manifest.routes[match.route.id];
116208
+ if (route) {
116209
+ let mod = await loadRouteModule(route, routeModules);
116210
+ return mod.links ? mod.links() : [];
116211
+ }
116212
+ return [];
116213
+ }));
116214
+ return dedupeLinkDescriptors(links.flat(1).filter(isHtmlLinkDescriptor).filter((link)=>link.rel === "stylesheet" || link.rel === "preload").map((link)=>link.rel === "stylesheet" ? {
116215
+ ...link,
116216
+ rel: "prefetch",
116217
+ as: "style"
116218
+ } : {
116219
+ ...link,
116220
+ rel: "prefetch"
116221
+ }));
116222
+ }
116223
+ function getNewMatchesForLinks(page, nextMatches, currentMatches, manifest, location, mode) {
116224
+ let isNew = (match, index)=>{
116225
+ if (!currentMatches[index]) return true;
116226
+ return match.route.id !== currentMatches[index].route.id;
116227
+ };
116228
+ let matchPathChanged = (match, index)=>{
116229
+ return(// param change, /users/123 -> /users/456
116230
+ currentMatches[index].pathname !== match.pathname || // splat param changed, which is not present in match.path
116231
+ // e.g. /files/images/avatar.jpg -> files/finances.xls
116232
+ currentMatches[index].route.path?.endsWith("*") && currentMatches[index].params["*"] !== match.params["*"]);
116233
+ };
116234
+ if (mode === "assets") {
116235
+ return nextMatches.filter((match, index)=>isNew(match, index) || matchPathChanged(match, index));
116236
+ }
116237
+ if (mode === "data") {
116238
+ return nextMatches.filter((match, index)=>{
116239
+ let manifestRoute = manifest.routes[match.route.id];
116240
+ if (!manifestRoute || !manifestRoute.hasLoader) {
116241
+ return false;
116242
+ }
116243
+ if (isNew(match, index) || matchPathChanged(match, index)) {
116244
+ return true;
116245
+ }
116246
+ if (match.route.shouldRevalidate) {
116247
+ let routeChoice = match.route.shouldRevalidate({
116248
+ currentUrl: new URL(location.pathname + location.search + location.hash, window.origin),
116249
+ currentParams: currentMatches[0]?.params || {},
116250
+ nextUrl: new URL(page, window.origin),
116251
+ nextParams: match.params,
116252
+ defaultShouldRevalidate: true
116253
+ });
116254
+ if (typeof routeChoice === "boolean") {
116255
+ return routeChoice;
116256
+ }
116257
+ }
116258
+ return true;
116259
+ });
116260
+ }
116261
+ return [];
116262
+ }
116263
+ function getModuleLinkHrefs(matches, manifest, { includeHydrateFallback } = {}) {
116264
+ return dedupeHrefs(matches.map((match)=>{
116265
+ let route = manifest.routes[match.route.id];
116266
+ if (!route) return [];
116267
+ let hrefs = [
116268
+ route.module
116269
+ ];
116270
+ if (route.clientActionModule) {
116271
+ hrefs = hrefs.concat(route.clientActionModule);
116272
+ }
116273
+ if (route.clientLoaderModule) {
116274
+ hrefs = hrefs.concat(route.clientLoaderModule);
116275
+ }
116276
+ if (includeHydrateFallback && route.hydrateFallbackModule) {
116277
+ hrefs = hrefs.concat(route.hydrateFallbackModule);
116278
+ }
116279
+ if (route.imports) {
116280
+ hrefs = hrefs.concat(route.imports);
116281
+ }
116282
+ return hrefs;
116283
+ }).flat(1));
116284
+ }
116285
+ function dedupeHrefs(hrefs) {
116286
+ return [
116287
+ ...new Set(hrefs)
116288
+ ];
116289
+ }
116290
+ function sortKeys(obj) {
116291
+ let sorted = {};
116292
+ let keys = Object.keys(obj).sort();
116293
+ for (let key of keys){
116294
+ sorted[key] = obj[key];
116295
+ }
116296
+ return sorted;
116297
+ }
116298
+ function dedupeLinkDescriptors(descriptors, preloads) {
116299
+ let set = /* @__PURE__ */ new Set();
116300
+ new Set(preloads);
116301
+ return descriptors.reduce((deduped, descriptor)=>{
116302
+ let key = JSON.stringify(sortKeys(descriptor));
116303
+ if (!set.has(key)) {
116304
+ set.add(key);
116305
+ deduped.push({
116306
+ key,
116307
+ link: descriptor
116308
+ });
116309
+ }
116310
+ return deduped;
116311
+ }, []);
116312
+ }
116313
+ // lib/dom/ssr/components.tsx
116314
+ function useDataRouterContext2() {
116315
+ let context = React.useContext(DataRouterContext);
116316
+ invariant2(context, "You must render this element inside a <DataRouterContext.Provider> element");
116317
+ return context;
116318
+ }
116319
+ function useDataRouterStateContext() {
116320
+ let context = React.useContext(DataRouterStateContext);
116321
+ invariant2(context, "You must render this element inside a <DataRouterStateContext.Provider> element");
116322
+ return context;
116323
+ }
116324
+ var FrameworkContext = React.createContext(void 0);
116325
+ FrameworkContext.displayName = "FrameworkContext";
116326
+ function useFrameworkContext() {
116327
+ let context = React.useContext(FrameworkContext);
116328
+ invariant2(context, "You must render this element inside a <HydratedRouter> element");
116329
+ return context;
116330
+ }
116331
+ function usePrefetchBehavior(prefetch, theirElementProps) {
116332
+ let frameworkContext = React.useContext(FrameworkContext);
116333
+ let [maybePrefetch, setMaybePrefetch] = React.useState(false);
116334
+ let [shouldPrefetch, setShouldPrefetch] = React.useState(false);
116335
+ let { onFocus, onBlur, onMouseEnter, onMouseLeave, onTouchStart } = theirElementProps;
116336
+ let ref = React.useRef(null);
116337
+ React.useEffect(()=>{
116338
+ if (prefetch === "render") {
116339
+ setShouldPrefetch(true);
116340
+ }
116341
+ if (prefetch === "viewport") {
116342
+ let callback = (entries)=>{
116343
+ entries.forEach((entry)=>{
116344
+ setShouldPrefetch(entry.isIntersecting);
116345
+ });
116346
+ };
116347
+ let observer = new IntersectionObserver(callback, {
116348
+ threshold: 0.5
116349
+ });
116350
+ if (ref.current) observer.observe(ref.current);
116351
+ return ()=>{
116352
+ observer.disconnect();
116353
+ };
116354
+ }
116355
+ }, [
116356
+ prefetch
116357
+ ]);
116358
+ React.useEffect(()=>{
116359
+ if (maybePrefetch) {
116360
+ let id = setTimeout(()=>{
116361
+ setShouldPrefetch(true);
116362
+ }, 100);
116363
+ return ()=>{
116364
+ clearTimeout(id);
116365
+ };
116366
+ }
116367
+ }, [
116368
+ maybePrefetch
116369
+ ]);
116370
+ let setIntent = ()=>{
116371
+ setMaybePrefetch(true);
116372
+ };
116373
+ let cancelIntent = ()=>{
116374
+ setMaybePrefetch(false);
116375
+ setShouldPrefetch(false);
116376
+ };
116377
+ if (!frameworkContext) {
116378
+ return [
116379
+ false,
116380
+ ref,
116381
+ {}
116382
+ ];
116383
+ }
116384
+ if (prefetch !== "intent") {
116385
+ return [
116386
+ shouldPrefetch,
116387
+ ref,
116388
+ {}
116389
+ ];
116390
+ }
116391
+ return [
116392
+ shouldPrefetch,
116393
+ ref,
116394
+ {
116395
+ onFocus: composeEventHandlers(onFocus, setIntent),
116396
+ onBlur: composeEventHandlers(onBlur, cancelIntent),
116397
+ onMouseEnter: composeEventHandlers(onMouseEnter, setIntent),
116398
+ onMouseLeave: composeEventHandlers(onMouseLeave, cancelIntent),
116399
+ onTouchStart: composeEventHandlers(onTouchStart, setIntent)
116400
+ }
116401
+ ];
116402
+ }
116403
+ function composeEventHandlers(theirHandler, ourHandler) {
116404
+ return (event)=>{
116405
+ theirHandler && theirHandler(event);
116406
+ if (!event.defaultPrevented) {
116407
+ ourHandler(event);
116408
+ }
116409
+ };
116410
+ }
116411
+ function PrefetchPageLinks({ page, ...linkProps }) {
116412
+ let { router } = useDataRouterContext2();
116413
+ let matches = React.useMemo(()=>matchRoutes(router.routes, page, router.basename), [
116414
+ router.routes,
116415
+ page,
116416
+ router.basename
116417
+ ]);
116418
+ if (!matches) {
116419
+ return null;
116420
+ }
116421
+ return /* @__PURE__ */ React.createElement(PrefetchPageLinksImpl, {
116422
+ page,
116423
+ matches,
116424
+ ...linkProps
116425
+ });
116426
+ }
116427
+ function useKeyedPrefetchLinks(matches) {
116428
+ let { manifest, routeModules } = useFrameworkContext();
116429
+ let [keyedPrefetchLinks, setKeyedPrefetchLinks] = React.useState([]);
116430
+ React.useEffect(()=>{
116431
+ let interrupted = false;
116432
+ void getKeyedPrefetchLinks(matches, manifest, routeModules).then((links)=>{
116433
+ if (!interrupted) {
116434
+ setKeyedPrefetchLinks(links);
116435
+ }
116436
+ });
116437
+ return ()=>{
116438
+ interrupted = true;
116439
+ };
116440
+ }, [
116441
+ matches,
116442
+ manifest,
116443
+ routeModules
116444
+ ]);
116445
+ return keyedPrefetchLinks;
116446
+ }
116447
+ function PrefetchPageLinksImpl({ page, matches: nextMatches, ...linkProps }) {
116448
+ let location = useLocation();
116449
+ let { future, manifest, routeModules } = useFrameworkContext();
116450
+ let { basename } = useDataRouterContext2();
116451
+ let { loaderData, matches } = useDataRouterStateContext();
116452
+ let newMatchesForData = React.useMemo(()=>getNewMatchesForLinks(page, nextMatches, matches, manifest, location, "data"), [
116453
+ page,
116454
+ nextMatches,
116455
+ matches,
116456
+ manifest,
116457
+ location
116458
+ ]);
116459
+ let newMatchesForAssets = React.useMemo(()=>getNewMatchesForLinks(page, nextMatches, matches, manifest, location, "assets"), [
116460
+ page,
116461
+ nextMatches,
116462
+ matches,
116463
+ manifest,
116464
+ location
116465
+ ]);
116466
+ let dataHrefs = React.useMemo(()=>{
116467
+ if (page === location.pathname + location.search + location.hash) {
116468
+ return [];
116469
+ }
116470
+ let routesParams = /* @__PURE__ */ new Set();
116471
+ let foundOptOutRoute = false;
116472
+ nextMatches.forEach((m)=>{
116473
+ let manifestRoute = manifest.routes[m.route.id];
116474
+ if (!manifestRoute || !manifestRoute.hasLoader) {
116475
+ return;
116476
+ }
116477
+ if (!newMatchesForData.some((m2)=>m2.route.id === m.route.id) && m.route.id in loaderData && routeModules[m.route.id]?.shouldRevalidate) {
116478
+ foundOptOutRoute = true;
116479
+ } else if (manifestRoute.hasClientLoader) {
116480
+ foundOptOutRoute = true;
116481
+ } else {
116482
+ routesParams.add(m.route.id);
116483
+ }
116484
+ });
116485
+ if (routesParams.size === 0) {
116486
+ return [];
116487
+ }
116488
+ let url = singleFetchUrl(page, basename, future.unstable_trailingSlashAwareDataRequests, "data");
116489
+ if (foundOptOutRoute && routesParams.size > 0) {
116490
+ url.searchParams.set("_routes", nextMatches.filter((m)=>routesParams.has(m.route.id)).map((m)=>m.route.id).join(","));
116491
+ }
116492
+ return [
116493
+ url.pathname + url.search
116494
+ ];
116495
+ }, [
116496
+ basename,
116497
+ future.unstable_trailingSlashAwareDataRequests,
116498
+ loaderData,
116499
+ location,
116500
+ manifest,
116501
+ newMatchesForData,
116502
+ nextMatches,
116503
+ page,
116504
+ routeModules
116505
+ ]);
116506
+ let moduleHrefs = React.useMemo(()=>getModuleLinkHrefs(newMatchesForAssets, manifest), [
116507
+ newMatchesForAssets,
116508
+ manifest
116509
+ ]);
116510
+ let keyedPrefetchLinks = useKeyedPrefetchLinks(newMatchesForAssets);
116511
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, dataHrefs.map((href)=>/* @__PURE__ */ React.createElement("link", {
116512
+ key: href,
116513
+ rel: "prefetch",
116514
+ as: "fetch",
116515
+ href,
116516
+ ...linkProps
116517
+ })), moduleHrefs.map((href)=>/* @__PURE__ */ React.createElement("link", {
116518
+ key: href,
116519
+ rel: "modulepreload",
116520
+ href,
116521
+ ...linkProps
116522
+ })), keyedPrefetchLinks.map(({ key, link })=>// these don't spread `linkProps` because they are full link descriptors
116523
+ // already with their own props
116524
+ /* @__PURE__ */ React.createElement("link", {
116525
+ key,
116526
+ nonce: linkProps.nonce,
116527
+ ...link,
116528
+ crossOrigin: link.crossOrigin ?? linkProps.crossOrigin
116529
+ })));
116530
+ }
116531
+ function mergeRefs(...refs) {
116532
+ return (value)=>{
116533
+ refs.forEach((ref)=>{
116534
+ if (typeof ref === "function") {
116535
+ ref(value);
116536
+ } else if (ref != null) {
116537
+ ref.current = value;
116538
+ }
116539
+ });
116540
+ };
116541
+ }
116542
+ var isBrowser2 = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
116543
+ try {
116544
+ if (isBrowser2) {
116545
+ window.__reactRouterVersion = "7.13.1";
116546
+ }
116547
+ } catch (e) {}
116548
+ var ABSOLUTE_URL_REGEX2 = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
116549
+ var Link = React.forwardRef(function LinkWithRef({ onClick, discover = "render", prefetch = "none", relative, reloadDocument, replace: replace2, unstable_mask, state, target, to, preventScrollReset, viewTransition, unstable_defaultShouldRevalidate, ...rest }, forwardedRef) {
116550
+ let { basename, navigator, unstable_useTransitions } = React.useContext(NavigationContext);
116551
+ let isAbsolute = typeof to === "string" && ABSOLUTE_URL_REGEX2.test(to);
116552
+ let parsed = parseToInfo(to, basename);
116553
+ to = parsed.to;
116554
+ let href = useHref(to, {
116555
+ relative
116556
+ });
116557
+ let location = useLocation();
116558
+ let maskedHref = null;
116559
+ if (unstable_mask) {
116560
+ let resolved = resolveTo(unstable_mask, [], location.unstable_mask ? location.unstable_mask.pathname : "/", true);
116561
+ if (basename !== "/") {
116562
+ resolved.pathname = resolved.pathname === "/" ? basename : joinPaths([
116563
+ basename,
116564
+ resolved.pathname
116565
+ ]);
116566
+ }
116567
+ maskedHref = navigator.createHref(resolved);
116568
+ }
116569
+ let [shouldPrefetch, prefetchRef, prefetchHandlers] = usePrefetchBehavior(prefetch, rest);
116570
+ let internalOnClick = useLinkClickHandler(to, {
116571
+ replace: replace2,
116572
+ unstable_mask,
116573
+ state,
116574
+ target,
116575
+ preventScrollReset,
116576
+ relative,
116577
+ viewTransition,
116578
+ unstable_defaultShouldRevalidate,
116579
+ unstable_useTransitions
116580
+ });
116581
+ function handleClick(event) {
116582
+ if (onClick) onClick(event);
116583
+ if (!event.defaultPrevented) {
116584
+ internalOnClick(event);
116585
+ }
116586
+ }
116587
+ let isSpaLink = !(parsed.isExternal || reloadDocument);
116588
+ let link = // eslint-disable-next-line jsx-a11y/anchor-has-content
116589
+ /* @__PURE__ */ React.createElement("a", {
116590
+ ...rest,
116591
+ ...prefetchHandlers,
116592
+ href: (isSpaLink ? maskedHref : void 0) || parsed.absoluteURL || href,
116593
+ onClick: isSpaLink ? handleClick : onClick,
116594
+ ref: mergeRefs(forwardedRef, prefetchRef),
116595
+ target,
116596
+ "data-discover": !isAbsolute && discover === "render" ? "true" : void 0
116597
+ });
116598
+ return shouldPrefetch && !isAbsolute ? /* @__PURE__ */ React.createElement(React.Fragment, null, link, /* @__PURE__ */ React.createElement(PrefetchPageLinks, {
116599
+ page: href
116600
+ })) : link;
116601
+ });
116602
+ Link.displayName = "Link";
116603
+ var NavLink = React.forwardRef(function NavLinkWithRef({ "aria-current": ariaCurrentProp = "page", caseSensitive = false, className: classNameProp = "", end = false, style: styleProp, to, viewTransition, children, ...rest }, ref) {
116604
+ let path = useResolvedPath(to, {
116605
+ relative: rest.relative
116606
+ });
116607
+ let location = useLocation();
116608
+ let routerState = React.useContext(DataRouterStateContext);
116609
+ let { navigator, basename } = React.useContext(NavigationContext);
116610
+ let isTransitioning = routerState != null && // Conditional usage is OK here because the usage of a data router is static
116611
+ // eslint-disable-next-line react-hooks/rules-of-hooks
116612
+ useViewTransitionState(path) && viewTransition === true;
116613
+ let toPathname = navigator.encodeLocation ? navigator.encodeLocation(path).pathname : path.pathname;
116614
+ let locationPathname = location.pathname;
116615
+ let nextLocationPathname = routerState && routerState.navigation && routerState.navigation.location ? routerState.navigation.location.pathname : null;
116616
+ if (!caseSensitive) {
116617
+ locationPathname = locationPathname.toLowerCase();
116618
+ nextLocationPathname = nextLocationPathname ? nextLocationPathname.toLowerCase() : null;
116619
+ toPathname = toPathname.toLowerCase();
116620
+ }
116621
+ if (nextLocationPathname && basename) {
116622
+ nextLocationPathname = stripBasename(nextLocationPathname, basename) || nextLocationPathname;
116623
+ }
116624
+ const endSlashPosition = toPathname !== "/" && toPathname.endsWith("/") ? toPathname.length - 1 : toPathname.length;
116625
+ let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(endSlashPosition) === "/";
116626
+ let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(toPathname.length) === "/");
116627
+ let renderProps = {
116628
+ isActive,
116629
+ isPending,
116630
+ isTransitioning
116631
+ };
116632
+ let ariaCurrent = isActive ? ariaCurrentProp : void 0;
116633
+ let className;
116634
+ if (typeof classNameProp === "function") {
116635
+ className = classNameProp(renderProps);
116636
+ } else {
116637
+ className = [
116638
+ classNameProp,
116639
+ isActive ? "active" : null,
116640
+ isPending ? "pending" : null,
116641
+ isTransitioning ? "transitioning" : null
116642
+ ].filter(Boolean).join(" ");
116643
+ }
116644
+ let style = typeof styleProp === "function" ? styleProp(renderProps) : styleProp;
116645
+ return /* @__PURE__ */ React.createElement(Link, {
116646
+ ...rest,
116647
+ "aria-current": ariaCurrent,
116648
+ className,
116649
+ ref,
116650
+ style,
116651
+ to,
116652
+ viewTransition
116653
+ }, typeof children === "function" ? children(renderProps) : children);
116654
+ });
116655
+ NavLink.displayName = "NavLink";
116656
+ var Form = React.forwardRef(({ discover = "render", fetcherKey, navigate, reloadDocument, replace: replace2, state, method = defaultMethod, action, onSubmit, relative, preventScrollReset, viewTransition, unstable_defaultShouldRevalidate, ...props }, forwardedRef)=>{
116657
+ let { unstable_useTransitions } = React.useContext(NavigationContext);
116658
+ let submit = useSubmit();
116659
+ let formAction = useFormAction(action, {
116660
+ relative
116661
+ });
116662
+ let formMethod = method.toLowerCase() === "get" ? "get" : "post";
116663
+ let isAbsolute = typeof action === "string" && ABSOLUTE_URL_REGEX2.test(action);
116664
+ let submitHandler = (event)=>{
116665
+ onSubmit && onSubmit(event);
116666
+ if (event.defaultPrevented) return;
116667
+ event.preventDefault();
116668
+ let submitter = event.nativeEvent.submitter;
116669
+ let submitMethod = submitter?.getAttribute("formmethod") || method;
116670
+ let doSubmit = ()=>submit(submitter || event.currentTarget, {
116671
+ fetcherKey,
116672
+ method: submitMethod,
116673
+ navigate,
116674
+ replace: replace2,
116675
+ state,
116676
+ relative,
116677
+ preventScrollReset,
116678
+ viewTransition,
116679
+ unstable_defaultShouldRevalidate
116680
+ });
116681
+ if (unstable_useTransitions && navigate !== false) {
116682
+ React.startTransition(()=>doSubmit());
116683
+ } else {
116684
+ doSubmit();
116685
+ }
116686
+ };
116687
+ return /* @__PURE__ */ React.createElement("form", {
116688
+ ref: forwardedRef,
116689
+ method: formMethod,
116690
+ action: formAction,
116691
+ onSubmit: reloadDocument ? onSubmit : submitHandler,
116692
+ ...props,
116693
+ "data-discover": !isAbsolute && discover === "render" ? "true" : void 0
116694
+ });
116695
+ });
116696
+ Form.displayName = "Form";
116697
+ function getDataRouterConsoleError2(hookName) {
116698
+ return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`;
116699
+ }
116700
+ function useDataRouterContext3(hookName) {
116701
+ let ctx = React.useContext(DataRouterContext);
116702
+ invariant(ctx, getDataRouterConsoleError2(hookName));
116703
+ return ctx;
116704
+ }
116705
+ function useLinkClickHandler(to, { target, replace: replaceProp, unstable_mask, state, preventScrollReset, relative, viewTransition, unstable_defaultShouldRevalidate, unstable_useTransitions } = {}) {
116706
+ let navigate = useNavigate();
116707
+ let location = useLocation();
116708
+ let path = useResolvedPath(to, {
116709
+ relative
116710
+ });
116711
+ return React.useCallback((event)=>{
116712
+ if (shouldProcessLinkClick(event, target)) {
116713
+ event.preventDefault();
116714
+ let replace2 = replaceProp !== void 0 ? replaceProp : createPath(location) === createPath(path);
116715
+ let doNavigate = ()=>navigate(to, {
116716
+ replace: replace2,
116717
+ unstable_mask,
116718
+ state,
116719
+ preventScrollReset,
116720
+ relative,
116721
+ viewTransition,
116722
+ unstable_defaultShouldRevalidate
116723
+ });
116724
+ if (unstable_useTransitions) {
116725
+ React.startTransition(()=>doNavigate());
116726
+ } else {
116727
+ doNavigate();
116728
+ }
116729
+ }
116730
+ }, [
116731
+ location,
116732
+ navigate,
116733
+ path,
116734
+ replaceProp,
116735
+ unstable_mask,
116736
+ state,
116737
+ target,
116738
+ to,
116739
+ preventScrollReset,
116740
+ relative,
116741
+ viewTransition,
116742
+ unstable_defaultShouldRevalidate,
116743
+ unstable_useTransitions
116744
+ ]);
116745
+ }
116746
+ function useSearchParams(defaultInit) {
116747
+ warning(typeof URLSearchParams !== "undefined", `You cannot use the \`useSearchParams\` hook in a browser that does not support the URLSearchParams API. If you need to support Internet Explorer 11, we recommend you load a polyfill such as https://github.com/ungap/url-search-params.`);
116748
+ let defaultSearchParamsRef = React.useRef(createSearchParams(defaultInit));
116749
+ let hasSetSearchParamsRef = React.useRef(false);
116750
+ let location = useLocation();
116751
+ let searchParams = React.useMemo(()=>// Only merge in the defaults if we haven't yet called setSearchParams.
116752
+ // Once we call that we want those to take precedence, otherwise you can't
116753
+ // remove a param with setSearchParams({}) if it has an initial value
116754
+ getSearchParamsForLocation(location.search, hasSetSearchParamsRef.current ? null : defaultSearchParamsRef.current), [
116755
+ location.search
116756
+ ]);
116757
+ let navigate = useNavigate();
116758
+ let setSearchParams = React.useCallback((nextInit, navigateOptions)=>{
116759
+ const newSearchParams = createSearchParams(typeof nextInit === "function" ? nextInit(new URLSearchParams(searchParams)) : nextInit);
116760
+ hasSetSearchParamsRef.current = true;
116761
+ navigate("?" + newSearchParams, navigateOptions);
116762
+ }, [
116763
+ navigate,
116764
+ searchParams
116765
+ ]);
116766
+ return [
116767
+ searchParams,
116768
+ setSearchParams
116769
+ ];
116770
+ }
116771
+ var fetcherId = 0;
116772
+ var getUniqueFetcherId = ()=>`__${String(++fetcherId)}__`;
116773
+ function useSubmit() {
116774
+ let { router } = useDataRouterContext3("useSubmit" /* UseSubmit */ );
116775
+ let { basename } = React.useContext(NavigationContext);
116776
+ let currentRouteId = useRouteId();
116777
+ let routerFetch = router.fetch;
116778
+ let routerNavigate = router.navigate;
116779
+ return React.useCallback(async (target, options = {})=>{
116780
+ let { action, method, encType, formData, body } = getFormSubmissionInfo(target, basename);
116781
+ if (options.navigate === false) {
116782
+ let key = options.fetcherKey || getUniqueFetcherId();
116783
+ await routerFetch(key, currentRouteId, options.action || action, {
116784
+ unstable_defaultShouldRevalidate: options.unstable_defaultShouldRevalidate,
116785
+ preventScrollReset: options.preventScrollReset,
116786
+ formData,
116787
+ body,
116788
+ formMethod: options.method || method,
116789
+ formEncType: options.encType || encType,
116790
+ flushSync: options.flushSync
116791
+ });
116792
+ } else {
116793
+ await routerNavigate(options.action || action, {
116794
+ unstable_defaultShouldRevalidate: options.unstable_defaultShouldRevalidate,
116795
+ preventScrollReset: options.preventScrollReset,
116796
+ formData,
116797
+ body,
116798
+ formMethod: options.method || method,
116799
+ formEncType: options.encType || encType,
116800
+ replace: options.replace,
116801
+ state: options.state,
116802
+ fromRouteId: currentRouteId,
116803
+ flushSync: options.flushSync,
116804
+ viewTransition: options.viewTransition
116805
+ });
116806
+ }
116807
+ }, [
116808
+ routerFetch,
116809
+ routerNavigate,
116810
+ basename,
116811
+ currentRouteId
116812
+ ]);
116813
+ }
116814
+ function useFormAction(action, { relative } = {}) {
116815
+ let { basename } = React.useContext(NavigationContext);
116816
+ let routeContext = React.useContext(RouteContext);
116817
+ invariant(routeContext, "useFormAction must be used inside a RouteContext");
116818
+ let [match] = routeContext.matches.slice(-1);
116819
+ let path = {
116820
+ ...useResolvedPath(action ? action : ".", {
116821
+ relative
116822
+ })
116823
+ };
116824
+ let location = useLocation();
116825
+ if (action == null) {
116826
+ path.search = location.search;
116827
+ let params = new URLSearchParams(path.search);
116828
+ let indexValues = params.getAll("index");
116829
+ let hasNakedIndexParam = indexValues.some((v)=>v === "");
116830
+ if (hasNakedIndexParam) {
116831
+ params.delete("index");
116832
+ indexValues.filter((v)=>v).forEach((v)=>params.append("index", v));
116833
+ let qs = params.toString();
116834
+ path.search = qs ? `?${qs}` : "";
116835
+ }
116836
+ }
116837
+ if ((!action || action === ".") && match.route.index) {
116838
+ path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
116839
+ }
116840
+ if (basename !== "/") {
116841
+ path.pathname = path.pathname === "/" ? basename : joinPaths([
116842
+ basename,
116843
+ path.pathname
116844
+ ]);
116845
+ }
116846
+ return createPath(path);
116847
+ }
116848
+ function useViewTransitionState(to, { relative } = {}) {
116849
+ let vtContext = React.useContext(ViewTransitionContext);
116850
+ invariant(vtContext != null, "`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");
116851
+ let { basename } = useDataRouterContext3("useViewTransitionState" /* useViewTransitionState */ );
116852
+ let path = useResolvedPath(to, {
116853
+ relative
116854
+ });
116855
+ if (!vtContext.isTransitioning) {
116856
+ return false;
116857
+ }
116858
+ let currentPath = stripBasename(vtContext.currentLocation.pathname, basename) || vtContext.currentLocation.pathname;
116859
+ let nextPath = stripBasename(vtContext.nextLocation.pathname, basename) || vtContext.nextLocation.pathname;
116860
+ return matchPath(path.pathname, nextPath) != null || matchPath(path.pathname, currentPath) != null;
116861
+ }
116862
+
116863
+ const EvaluationsMockContext = /*#__PURE__*/ createContext(undefined);
116864
+ const useEvaluationsMock = ()=>{
116865
+ return useContext(EvaluationsMockContext);
116866
+ };
116867
+
116868
+ const API_BASE = "/api";
116869
+ const useEvaluations = ()=>{
116870
+ const mockContext = useEvaluationsMock();
116871
+ const [evaluations, setEvaluations] = useState([]);
116872
+ const [loading, setLoading] = useState(false);
116873
+ const [error, setError] = useState(null);
116874
+ const fetchEvaluations = useCallback(async ()=>{
116875
+ setLoading(true);
116876
+ setError(null);
116877
+ try {
116878
+ // Check for mock data first
116879
+ if (mockContext?.mockEvaluations) {
116880
+ setEvaluations(mockContext.mockEvaluations);
116881
+ setLoading(false);
116882
+ return;
116883
+ }
116884
+ // Otherwise fetch from API (returns raw DTO)
116885
+ const response = await fetch(`${API_BASE}/evaluations`);
116886
+ if (!response.ok) {
116887
+ throw new Error(`HTTP error! status: ${response.status}`);
116888
+ }
116889
+ const data = await response.json();
116890
+ // Handle edge cases: null/undefined or not an array
116891
+ if (!data || !Array.isArray(data)) {
116892
+ setEvaluations([]);
116893
+ return;
116894
+ }
116895
+ setEvaluations(data);
116896
+ } catch (err) {
116897
+ const errorMessage = err instanceof Error ? err.message : "Unknown error occurred";
116898
+ setError(errorMessage);
116899
+ setEvaluations([]);
116900
+ } finally{
116901
+ setLoading(false);
116902
+ }
116903
+ }, [
116904
+ mockContext
116905
+ ]);
116906
+ useEffect(()=>{
116907
+ fetchEvaluations();
116908
+ }, [
116909
+ fetchEvaluations
116910
+ ]);
116911
+ return {
116912
+ evaluations,
116913
+ loading,
116914
+ error,
116915
+ refetch: fetchEvaluations
116916
+ };
116917
+ };
116918
+
116919
+ const EvaluationsComparePage = ({ backHref = "#/evaluations" })=>{
116920
+ const { evaluations, loading, error } = useEvaluations();
116921
+ const [searchParams, setSearchParams] = useSearchParams();
116922
+ const normalizedEvaluations = React__default.useMemo(()=>evaluations.map((e)=>isEvaluationDto(e) ? transformEvaluation(e) : e), [
116923
+ evaluations
116924
+ ]);
116925
+ // Support compare=id1,id2 (primary) and legacy evaluationId1/evaluationId2, source/target
116926
+ const [evaluationId1, evaluationId2] = React__default.useMemo(()=>{
116927
+ const compareParam = searchParams.get("compare");
116928
+ if (compareParam) {
116929
+ const [id1, id2] = compareParam.split(",").map((s)=>s.trim()).filter(Boolean);
116930
+ return [
116931
+ id1 ?? null,
116932
+ id2 ?? null
116933
+ ];
116934
+ }
116935
+ const id1 = searchParams.get("evaluationId1") ?? searchParams.get("source");
116936
+ const id2 = searchParams.get("evaluationId2") ?? searchParams.get("target");
116937
+ return [
116938
+ id1,
116939
+ id2
116940
+ ];
116941
+ }, [
116942
+ searchParams
116943
+ ]);
116944
+ const updateCompareParam = React__default.useCallback((id1, id2)=>{
116945
+ const newParams = new URLSearchParams(searchParams);
116946
+ newParams.delete("evaluationId1");
116947
+ newParams.delete("evaluationId2");
116948
+ newParams.delete("source");
116949
+ newParams.delete("target");
116950
+ if (id1 && id2) {
116951
+ newParams.set("compare", `${id1},${id2}`);
116952
+ } else {
116953
+ newParams.delete("compare");
116954
+ }
116955
+ setSearchParams(newParams, {
116956
+ replace: true
116957
+ });
116958
+ }, [
116959
+ searchParams,
116960
+ setSearchParams
116961
+ ]);
116962
+ const handleEvaluationId1Change = (id)=>{
116963
+ updateCompareParam(id, evaluationId2);
116964
+ };
116965
+ const handleEvaluationId2Change = (id)=>{
116966
+ updateCompareParam(evaluationId1, id);
116967
+ };
116968
+ if (error) {
116969
+ return /*#__PURE__*/ React__default.createElement("div", {
116970
+ style: {
116971
+ padding: "24px",
116972
+ textAlign: "center"
116973
+ }
116974
+ }, /*#__PURE__*/ React__default.createElement("p", {
116975
+ style: {
116976
+ color: "red"
116977
+ }
116978
+ }, "Error loading evaluations: ", error));
116979
+ }
116980
+ return /*#__PURE__*/ React__default.createElement("div", {
116981
+ style: {
116982
+ padding: "24px"
116983
+ }
116984
+ }, /*#__PURE__*/ React__default.createElement("h1", {
116985
+ style: {
116986
+ margin: "0 0 24px 0",
116987
+ fontSize: "24px",
116988
+ fontWeight: 600
116989
+ }
116990
+ }, "Compare Evaluations"), /*#__PURE__*/ React__default.createElement(EvaluationsCompareView, {
116991
+ evaluations: normalizedEvaluations,
116992
+ evaluationId1: evaluationId1,
116993
+ evaluationId2: evaluationId2,
116994
+ onEvaluationId1Change: handleEvaluationId1Change,
116995
+ onEvaluationId2Change: handleEvaluationId2Change,
116996
+ loading: loading,
116997
+ showEvaluationComparisonDropdowns: true,
116998
+ backHref: backHref
116999
+ }));
117000
+ };
117001
+
114390
117002
  function isLLMNode(n) {
114391
117003
  return isLLMResult(n);
114392
117004
  }
@@ -117549,6 +120161,15 @@ const GlobalStyles = ()=>{
117549
120161
  border-bottom-right-radius: 0.5rem !important;
117550
120162
  }
117551
120163
 
120164
+ /* Evaluations compare: highlight rows with differing values */
120165
+ .ant-table-tbody > tr.evaluations-compare-diff-row > td {
120166
+ background-color: #fef9c3 !important;
120167
+ }
120168
+
120169
+ html.dark .ant-table-tbody > tr.evaluations-compare-diff-row > td {
120170
+ background-color: #334155 !important;
120171
+ }
120172
+
117552
120173
  /* CSS Variables for backward compatibility */
117553
120174
  :root {
117554
120175
  --background: #ffffff;
@@ -117736,4 +120357,4 @@ const GlobalStyles = ()=>{
117736
120357
  return getSafeColor(props.theme, path, fallback);
117737
120358
  };
117738
120359
 
117739
- export { AgenticFlowVisualizer, AnthropicIcon, AppleIcon, Badge, Drawer, Edge, EvaluationDetailsDrawer, EvaluationsCompare, EvaluationsTable, EvaluatorResult, GlobalStyles, GoogleIcon, JsonTreeViewer, Node$1 as Node, OllamaIcon, OpenAIIcon, SafeThemeProvider, SessionDetails, Sheet, ThemeProvider, Timeline, Visualizer, calculateAutoLayout, cn, conditionalStyle, createSafeTheme, darkTheme, defaultTheme$1 as defaultTheme, detectContentType, formatCurrency, formatDateFriendly, formatDateRelative, formatDateShort, formatDuration, formatLatency, formatMetricValue, formatNumberWithCommas, formatToolCalls, getColor, getSafeColor, getSafeSpacing, getSafeThemeValue, getSpacing, getStatusColor, isEvaluationDto, lightTheme, safeStyled, safeThemeColor, safeThemeSpacing, safeThemeValue, toTitleCase, transformEvaluation, truncateText, useComponentTheme, useSafeTheme, useTheme$1 as useTheme, useThemeValue };
120360
+ export { AgenticFlowVisualizer, AnthropicIcon, AppleIcon, Badge, Drawer, Edge, EvaluationDetailsDrawer, EvaluationsCompareDrawer, EvaluationsComparePage, EvaluationsCompareView, EvaluationsTable, EvaluatorResult, GlobalStyles, GoogleIcon, JsonTreeViewer, Node$1 as Node, OllamaIcon, OpenAIIcon, SafeThemeProvider, SessionDetails, Sheet, ThemeProvider, Timeline, Visualizer, calculateAutoLayout, cn, conditionalStyle, createSafeTheme, darkTheme, defaultTheme$1 as defaultTheme, detectContentType, evaluationsHaveSameMetrics, formatCurrency, formatDateFriendly, formatDateRelative, formatDateShort, formatDuration, formatLatency, formatMetricValue$1 as formatMetricValue, formatNumberWithCommas, formatToolCalls, getColor, getSafeColor, getSafeSpacing, getSafeThemeValue, getSpacing, getStatusColor, isEvaluationDto, lightTheme, safeStyled, safeThemeColor, safeThemeSpacing, safeThemeValue, toTitleCase, transformEvaluation, truncateText, useComponentTheme, useSafeTheme, useTheme$1 as useTheme, useThemeValue };