@parca/profile 0.16.122 → 0.16.123

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/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.16.123](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.122...@parca/profile@0.16.123) (2023-02-22)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
6
10
  ## [0.16.122](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.121...@parca/profile@0.16.122) (2023-02-22)
7
11
 
8
12
  **Note:** Version bump only for package @parca/profile
@@ -194,14 +194,14 @@ export var RawMetricsGraph = function (_a) {
194
194
  var s = null;
195
195
  var seriesIndex = -1;
196
196
  outer: for (var i = 0; i < series.length; i++) {
197
- var keys = profile.labels.map(function (e) { return e.name; });
197
+ var keys = profile.query.matchers.map(function (e) { return e.key; });
198
198
  var _loop_1 = function (j) {
199
- var labelName = keys[j];
200
- var label = series[i].metric.find(function (e) { return e.name === labelName; });
199
+ var matcherKey = keys[j];
200
+ var label = series[i].metric.find(function (e) { return e.name === matcherKey; });
201
201
  if (label === undefined) {
202
202
  return "continue-outer";
203
203
  }
204
- if (profile.labels[j].value !== label.value) {
204
+ if (profile.query.matchers[j].value !== label.value) {
205
205
  return "continue-outer";
206
206
  }
207
207
  };
@@ -8,7 +8,6 @@ interface IcicleGraphProps {
8
8
  curPath: string[];
9
9
  setCurPath: (path: string[]) => void;
10
10
  navigateTo?: NavigateFunction;
11
- isTrimmed?: boolean;
12
11
  }
13
12
  export declare const IcicleGraph: import("react").NamedExoticComponent<IcicleGraphProps>;
14
13
  export default IcicleGraph;
@@ -23,30 +23,22 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
23
23
  // See the License for the specific language governing permissions and
24
24
  // limitations under the License.
25
25
  import { memo, useEffect, useMemo, useRef, useState } from 'react';
26
- import cx from 'classnames';
27
26
  import { scaleLinear } from 'd3-scale';
28
- import { Button, useURLState } from '@parca/components';
29
27
  import { selectQueryParam } from '@parca/functions';
30
- import useUserPreference, { USER_PREFERENCES } from '@parca/functions/useUserPreference';
31
28
  import GraphTooltip from '../../GraphTooltip';
32
29
  import ColorStackLegend from './ColorStackLegend';
33
30
  import { IcicleNode, RowHeight } from './IcicleGraphNodes';
34
31
  import useColoredGraph from './useColoredGraph';
35
32
  export var IcicleGraph = memo(function IcicleGraph(_a) {
36
33
  var _b;
37
- var graph = _a.graph, width = _a.width, setCurPath = _a.setCurPath, curPath = _a.curPath, sampleUnit = _a.sampleUnit, navigateTo = _a.navigateTo, _c = _a.isTrimmed, isTrimmed = _c === void 0 ? false : _c;
38
- var _d = useState(), hoveringNode = _d[0], setHoveringNode = _d[1];
39
- var _e = useState(0), height = _e[0], setHeight = _e[1];
34
+ var graph = _a.graph, width = _a.width, setCurPath = _a.setCurPath, curPath = _a.curPath, sampleUnit = _a.sampleUnit, navigateTo = _a.navigateTo;
35
+ var _c = useState(), hoveringNode = _c[0], setHoveringNode = _c[1];
36
+ var _d = useState(0), height = _d[0], setHeight = _d[1];
40
37
  var svg = useRef(null);
41
38
  var ref = useRef(null);
42
- var rawDashboardItems = useURLState({
43
- param: 'dashboard_items',
44
- })[0];
45
- var dashboardItems = rawDashboardItems;
46
39
  var coloredGraph = useColoredGraph(graph);
47
40
  var currentSearchString = (_b = selectQueryParam('search_string')) !== null && _b !== void 0 ? _b : '';
48
41
  var compareMode = selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
49
- var colorProfileName = useUserPreference(USER_PREFERENCES.FLAMEGRAPH_COLOR_PROFILE.key)[0];
50
42
  useEffect(function () {
51
43
  if (ref.current != null) {
52
44
  setHeight(ref === null || ref === void 0 ? void 0 : ref.current.getBoundingClientRect().height);
@@ -62,16 +54,6 @@ export var IcicleGraph = memo(function IcicleGraph(_a) {
62
54
  if (coloredGraph.root === undefined || width === undefined) {
63
55
  return _jsx(_Fragment, {});
64
56
  }
65
- var isColorStackLegendVisible = colorProfileName !== 'default';
66
- return (_jsxs("div", __assign({ onMouseLeave: function () { return setHoveringNode(undefined); } }, { children: [_jsx(ColorStackLegend, { navigateTo: navigateTo, compareMode: compareMode }), _jsx(GraphTooltip, { unit: sampleUnit, total: total, hoveringNode: hoveringNode, contextElement: svg.current, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function }), _jsx("div", __assign({ className: cx('flex justify-start absolute', {
67
- 'top-[-48px]': dashboardItems.length <= 1 && !isTrimmed && !isColorStackLegendVisible,
68
- 'top-[-69px]': dashboardItems.length <= 1 && !isTrimmed && isColorStackLegendVisible,
69
- 'top-[-54px]': dashboardItems.length <= 1 && isTrimmed && isColorStackLegendVisible,
70
- 'top-[-54px] ': dashboardItems.length <= 1 && isTrimmed && !isColorStackLegendVisible,
71
- 'top-[-54px] left-[25px]': dashboardItems.length > 1 && isTrimmed && isColorStackLegendVisible,
72
- 'top-[-54px] left-[25px] ': dashboardItems.length > 1 && isTrimmed && !isColorStackLegendVisible,
73
- 'top-[-70px] left-[25px]': dashboardItems.length > 1 && !isTrimmed && isColorStackLegendVisible,
74
- 'top-[-46px] left-[25px]': dashboardItems.length > 1 && !isTrimmed && !isColorStackLegendVisible,
75
- }) }, { children: _jsx(Button, __assign({ color: "neutral", onClick: function () { return setCurPath([]); }, disabled: curPath.length === 0, className: "w-auto", variant: "neutral" }, { children: "Reset View" })) })), _jsx("svg", __assign({ className: "font-robotoMono", width: width, height: height, preserveAspectRatio: "xMinYMid", ref: svg }, { children: _jsx("g", __assign({ ref: ref }, { children: _jsx("g", __assign({ transform: 'translate(0, 0)' }, { children: _jsx(IcicleNode, { x: 0, y: 0, totalWidth: width, height: RowHeight, setCurPath: setCurPath, setHoveringNode: setHoveringNode, curPath: curPath, data: coloredGraph.root, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function, total: total, xScale: xScale, path: [], level: 0, isRoot: true, searchString: currentSearchString, compareMode: compareMode }) })) })) }))] })));
57
+ return (_jsxs("div", __assign({ onMouseLeave: function () { return setHoveringNode(undefined); } }, { children: [_jsx(ColorStackLegend, { navigateTo: navigateTo, compareMode: compareMode }), _jsx(GraphTooltip, { unit: sampleUnit, total: total, hoveringNode: hoveringNode, contextElement: svg.current, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function }), _jsx("svg", __assign({ className: "font-robotoMono", width: width, height: height, preserveAspectRatio: "xMinYMid", ref: svg }, { children: _jsx("g", __assign({ ref: ref }, { children: _jsx("g", __assign({ transform: 'translate(0, 0)' }, { children: _jsx(IcicleNode, { x: 0, y: 0, totalWidth: width, height: RowHeight, setCurPath: setCurPath, setHoveringNode: setHoveringNode, curPath: curPath, data: coloredGraph.root, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function, total: total, xScale: xScale, path: [], level: 0, isRoot: true, searchString: currentSearchString, compareMode: compareMode }) })) })) }))] })));
76
58
  });
77
59
  export default IcicleGraph;
@@ -10,6 +10,7 @@ interface ProfileIcicleGraphProps {
10
10
  onContainerResize?: ResizeHandler;
11
11
  navigateTo?: NavigateFunction;
12
12
  loading: boolean;
13
+ setActionButtons?: (buttons: JSX.Element) => void;
13
14
  }
14
- declare const ProfileIcicleGraph: ({ graph, curPath, setNewCurPath, sampleUnit, onContainerResize, navigateTo, loading, }: ProfileIcicleGraphProps) => JSX.Element;
15
+ declare const ProfileIcicleGraph: ({ graph, curPath, setNewCurPath, sampleUnit, onContainerResize, navigateTo, loading, setActionButtons, }: ProfileIcicleGraphProps) => JSX.Element;
15
16
  export default ProfileIcicleGraph;
@@ -23,13 +23,14 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
23
23
  // See the License for the specific language governing permissions and
24
24
  // limitations under the License.
25
25
  import { useEffect, useMemo } from 'react';
26
+ import { Button } from '@parca/components';
26
27
  import { useContainerDimensions } from '@parca/dynamicsize';
27
28
  import { selectQueryParam } from '@parca/functions';
28
29
  import DiffLegend from '../components/DiffLegend';
29
- import IcicleGraph from './IcicleGraph';
30
+ import { IcicleGraph } from './IcicleGraph';
30
31
  var numberFormatter = new Intl.NumberFormat('en-US');
31
32
  var ProfileIcicleGraph = function (_a) {
32
- var graph = _a.graph, curPath = _a.curPath, setNewCurPath = _a.setNewCurPath, sampleUnit = _a.sampleUnit, onContainerResize = _a.onContainerResize, navigateTo = _a.navigateTo, loading = _a.loading;
33
+ var graph = _a.graph, curPath = _a.curPath, setNewCurPath = _a.setNewCurPath, sampleUnit = _a.sampleUnit, onContainerResize = _a.onContainerResize, navigateTo = _a.navigateTo, loading = _a.loading, setActionButtons = _a.setActionButtons;
33
34
  var compareMode = selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
34
35
  var _b = useContainerDimensions(), ref = _b.ref, dimensions = _b.dimensions;
35
36
  useEffect(function () {
@@ -55,11 +56,17 @@ var ProfileIcicleGraph = function (_a) {
55
56
  numberFormatter.format(untrimmedTotal),
56
57
  ];
57
58
  }, [graph]), isTrimmed = _c[0], _ = _c[1], trimmedPercentage = _c[2], formattedTotal = _c[3], formattedUntrimmedTotal = _c[4];
59
+ useEffect(function () {
60
+ if (setActionButtons === undefined) {
61
+ return;
62
+ }
63
+ setActionButtons(_jsx(_Fragment, { children: _jsx(Button, __assign({ color: "neutral", onClick: function () { return setNewCurPath([]); }, disabled: curPath.length === 0, className: "w-auto", variant: "neutral" }, { children: "Reset View" })) }));
64
+ }, [setNewCurPath, curPath, setActionButtons]);
58
65
  if (graph === undefined)
59
66
  return _jsx("div", { children: "no data..." });
60
67
  var total = graph.total;
61
68
  if (parseFloat(total) === 0 && !loading)
62
69
  return _jsx(_Fragment, { children: "Profile has no samples" });
63
- return (_jsxs("div", __assign({ className: "relative" }, { children: [compareMode && _jsx(DiffLegend, {}), isTrimmed ? (_jsxs("p", __assign({ className: "my-2 text-sm" }, { children: ["Showing ", formattedTotal, "(", trimmedPercentage, "%) out of ", formattedUntrimmedTotal, " samples"] }))) : null, _jsx("div", __assign({ ref: ref }, { children: _jsx(IcicleGraph, { width: dimensions === null || dimensions === void 0 ? void 0 : dimensions.width, graph: graph, curPath: curPath, setCurPath: setNewCurPath, sampleUnit: sampleUnit, navigateTo: navigateTo, isTrimmed: isTrimmed }) }))] })));
70
+ return (_jsxs("div", __assign({ className: "relative" }, { children: [compareMode && _jsx(DiffLegend, {}), isTrimmed ? (_jsxs("p", __assign({ className: "my-2 text-sm" }, { children: ["Showing ", formattedTotal, "(", trimmedPercentage, "%) out of ", formattedUntrimmedTotal, " samples"] }))) : null, _jsx("div", __assign({ ref: ref }, { children: _jsx(IcicleGraph, { width: dimensions === null || dimensions === void 0 ? void 0 : dimensions.width, graph: graph, curPath: curPath, setCurPath: setNewCurPath, sampleUnit: sampleUnit, navigateTo: navigateTo }) }))] })));
64
71
  };
65
72
  export default ProfileIcicleGraph;
@@ -93,6 +93,7 @@ var ProfileSelector = function (_a) {
93
93
  var newValue = value.includes('\\') ? value.replaceAll('\\', '\\\\') : value;
94
94
  var _a = Query.parse(queryExpressionString).setMatcher(key, newValue), newQuery = _a[0], changed = _a[1];
95
95
  if (changed) {
96
+ // TODO: Change this to store the query object
96
97
  setNewQueryExpression(newQuery.toString());
97
98
  }
98
99
  };
@@ -130,12 +131,21 @@ var ProfileSelector = function (_a) {
130
131
  timeSelection: range.getRangeKey(),
131
132
  });
132
133
  }, addLabelMatcher: addLabelMatcher, onPointClick: function (timestamp, labels, queryExpression) {
134
+ // TODO: Pass the query object via click rather than queryExpression
135
+ var query = Query.parse(queryExpression);
136
+ labels.forEach(function (l) {
137
+ var _a = query.setMatcher(l.name, l.value), newQuery = _a[0], updated = _a[1];
138
+ if (updated) {
139
+ query = newQuery;
140
+ }
141
+ });
133
142
  var stepDuration = getStepDuration(querySelection.from, querySelection.to);
134
143
  var stepDurationInMilliseconds = getStepDurationInMilliseconds(stepDuration);
135
- var isDeltaType = Query.parse(queryExpression).profileType().delta;
136
144
  var mergeFrom = timestamp;
137
- var mergeTo = isDeltaType ? mergeFrom + stepDurationInMilliseconds : mergeFrom;
138
- selectProfile(new MergedProfileSelection(mergeFrom, mergeTo, labels, queryExpression));
145
+ var mergeTo = query.profileType().delta
146
+ ? mergeFrom + stepDurationInMilliseconds
147
+ : mergeFrom;
148
+ selectProfile(new MergedProfileSelection(mergeFrom, mergeTo, query));
139
149
  } })) : (_jsx(_Fragment, { children: profileSelection == null && (_jsx("div", __assign({ className: "my-20 text-center" }, { children: _jsx("p", { children: "Run a query, and the result will be displayed here." }) }))) })) })] }));
140
150
  };
141
151
  export default ProfileSelector;
@@ -1,5 +1,5 @@
1
1
  import { Label, ProfileDiffSelection, QueryRequest } from '@parca/client';
2
- import { ProfileType } from '@parca/parser';
2
+ import { ProfileType, Query } from '@parca/parser';
3
3
  export interface ProfileSource {
4
4
  QueryRequest: () => QueryRequest;
5
5
  ProfileType: () => ProfileType;
@@ -30,10 +30,9 @@ export declare function ProfileSelectionFromParams(expression: string | undefine
30
30
  export declare class MergedProfileSelection implements ProfileSelection {
31
31
  mergeFrom: number;
32
32
  mergeTo: number;
33
- query: string;
33
+ query: Query;
34
34
  filterQuery: string | undefined;
35
- labels: Label[];
36
- constructor(mergeFrom: number, mergeTo: number, labels: Label[], query: string, filterQuery?: string);
35
+ constructor(mergeFrom: number, mergeTo: number, query: Query, filterQuery?: string);
37
36
  ProfileName(): string;
38
37
  HistoryParams(): {
39
38
  [key: string]: any;
@@ -55,14 +54,13 @@ export declare class ProfileDiffSource implements ProfileSource {
55
54
  export declare class MergedProfileSource implements ProfileSource {
56
55
  mergeFrom: number;
57
56
  mergeTo: number;
58
- labels: Label[];
59
- query: string;
57
+ query: Query;
60
58
  filterQuery: string | undefined;
61
- constructor(mergeFrom: number, mergeTo: number, labels: Label[], query: string, filterQuery?: string);
59
+ constructor(mergeFrom: number, mergeTo: number, query: Query, filterQuery?: string);
62
60
  DiffSelection(): ProfileDiffSelection;
63
61
  QueryRequest(): QueryRequest;
64
62
  ProfileType(): ProfileType;
65
63
  Describe(): JSX.Element;
66
- stringLabels(): string[];
64
+ stringMatchers(): string[];
67
65
  toString(): string;
68
66
  }
@@ -30,7 +30,9 @@ export function SuffixParams(params, suffix) {
30
30
  }));
31
31
  }
32
32
  export function ParseLabels(labels) {
33
- return labels.map(function (labelString) {
33
+ return labels
34
+ .filter(function (str) { return str !== ''; })
35
+ .map(function (labelString) {
34
36
  var parts = labelString.split('=', 2);
35
37
  return { name: parts[0], value: parts[1] };
36
38
  });
@@ -41,20 +43,27 @@ export function ProfileSelectionFromParams(expression, from, to, mergeFrom, merg
41
43
  mergeFrom !== undefined &&
42
44
  mergeTo !== undefined &&
43
45
  expression !== undefined) {
44
- return new MergedProfileSelection(parseInt(mergeFrom), parseInt(mergeTo), ParseLabels(labels !== null && labels !== void 0 ? labels : ['']), expression, filterQuery);
46
+ // TODO: Refactor parsing the query and adding matchers
47
+ var query_1 = Query.parse(expression);
48
+ ParseLabels(labels !== null && labels !== void 0 ? labels : ['']).forEach(function (l) {
49
+ var _a = query_1.setMatcher(l.name, l.value), newQuery = _a[0], changed = _a[1];
50
+ if (changed) {
51
+ query_1 = newQuery;
52
+ }
53
+ });
54
+ return new MergedProfileSelection(parseInt(mergeFrom), parseInt(mergeTo), query_1, filterQuery);
45
55
  }
46
56
  return null;
47
57
  }
48
58
  var MergedProfileSelection = /** @class */ (function () {
49
- function MergedProfileSelection(mergeFrom, mergeTo, labels, query, filterQuery) {
59
+ function MergedProfileSelection(mergeFrom, mergeTo, query, filterQuery) {
50
60
  this.mergeFrom = mergeFrom;
51
61
  this.mergeTo = mergeTo;
52
62
  this.query = query;
53
63
  this.filterQuery = filterQuery;
54
- this.labels = labels;
55
64
  }
56
65
  MergedProfileSelection.prototype.ProfileName = function () {
57
- return Query.parse(this.query).profileName();
66
+ return this.query.profileName();
58
67
  };
59
68
  MergedProfileSelection.prototype.HistoryParams = function () {
60
69
  return {
@@ -62,14 +71,14 @@ var MergedProfileSelection = /** @class */ (function () {
62
71
  merge_to: this.mergeTo.toString(),
63
72
  query: this.query,
64
73
  profile_name: this.ProfileName(),
65
- labels: this.labels.map(function (label) { return "".concat(label.name, "=").concat(encodeURIComponent(label.value)); }),
74
+ labels: this.query.matchers.map(function (m) { return "".concat(m.key, "=").concat(encodeURIComponent(m.value)); }),
66
75
  };
67
76
  };
68
77
  MergedProfileSelection.prototype.Type = function () {
69
78
  return 'merge';
70
79
  };
71
80
  MergedProfileSelection.prototype.ProfileSource = function () {
72
- return new MergedProfileSource(this.mergeFrom, this.mergeTo, this.labels, this.query, this.filterQuery);
81
+ return new MergedProfileSource(this.mergeFrom, this.mergeTo, this.query, this.filterQuery);
73
82
  };
74
83
  return MergedProfileSelection;
75
84
  }());
@@ -110,10 +119,9 @@ var ProfileDiffSource = /** @class */ (function () {
110
119
  }());
111
120
  export { ProfileDiffSource };
112
121
  var MergedProfileSource = /** @class */ (function () {
113
- function MergedProfileSource(mergeFrom, mergeTo, labels, query, filterQuery) {
122
+ function MergedProfileSource(mergeFrom, mergeTo, query, filterQuery) {
114
123
  this.mergeFrom = mergeFrom;
115
124
  this.mergeTo = mergeTo;
116
- this.labels = labels;
117
125
  this.query = query;
118
126
  this.filterQuery = filterQuery;
119
127
  }
@@ -124,7 +132,7 @@ var MergedProfileSource = /** @class */ (function () {
124
132
  merge: {
125
133
  start: Timestamp.fromDate(new Date(this.mergeFrom)),
126
134
  end: Timestamp.fromDate(new Date(this.mergeTo)),
127
- query: this.query,
135
+ query: this.query.toString(),
128
136
  },
129
137
  },
130
138
  mode: ProfileDiffSelection_Mode.MERGE,
@@ -137,7 +145,7 @@ var MergedProfileSource = /** @class */ (function () {
137
145
  merge: {
138
146
  start: Timestamp.fromDate(new Date(this.mergeFrom)),
139
147
  end: Timestamp.fromDate(new Date(this.mergeTo)),
140
- query: this.query,
148
+ query: this.query.toString(),
141
149
  },
142
150
  },
143
151
  reportType: QueryRequest_ReportType.FLAMEGRAPH_UNSPECIFIED,
@@ -146,18 +154,18 @@ var MergedProfileSource = /** @class */ (function () {
146
154
  };
147
155
  };
148
156
  MergedProfileSource.prototype.ProfileType = function () {
149
- return ProfileType.fromString(Query.parse(this.query).profileName());
157
+ return ProfileType.fromString(Query.parse(this.query.toString()).profileName());
150
158
  };
151
159
  MergedProfileSource.prototype.Describe = function () {
152
- return (_jsxs("a", { children: ["Merge of \"", this.query, "\" from ", formatDate(this.mergeFrom, timeFormat), " to", ' ', formatDate(this.mergeTo, timeFormat)] }));
160
+ return (_jsxs("a", { children: ["Merge of \"", this.query.toString(), "\" from ", formatDate(this.mergeFrom, timeFormat), ' ', "to ", formatDate(this.mergeTo, timeFormat)] }));
153
161
  };
154
- MergedProfileSource.prototype.stringLabels = function () {
155
- return this.labels
156
- .filter(function (label) { return label.name !== '__name__'; })
157
- .map(function (label) { return "".concat(label.name, "=").concat(label.value); });
162
+ MergedProfileSource.prototype.stringMatchers = function () {
163
+ return this.query.matchers
164
+ .filter(function (m) { return m.key !== '__name__'; })
165
+ .map(function (m) { return "".concat(m.key, "=").concat(m.value); });
158
166
  };
159
167
  MergedProfileSource.prototype.toString = function () {
160
- return "merged profiles of query \"".concat(this.query, "\" from ").concat(formatDate(this.mergeFrom, timeFormat), " to ").concat(formatDate(this.mergeTo, timeFormat));
168
+ return "merged profiles of query \"".concat(this.query.toString(), "\" from ").concat(formatDate(this.mergeFrom, timeFormat), " to ").concat(formatDate(this.mergeTo, timeFormat));
161
169
  };
162
170
  return MergedProfileSource;
163
171
  }());
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import type { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd';
3
+ import type { NavigateFunction } from '@parca/functions';
4
+ interface Props {
5
+ dashboardItem: string;
6
+ index: number;
7
+ isMultiPanelView: boolean;
8
+ handleClosePanel: (dashboardItem: string) => void;
9
+ navigateTo: NavigateFunction | undefined;
10
+ dragHandleProps: DraggableProvidedDragHandleProps | null | undefined;
11
+ getDashboardItemByType: (props: {
12
+ type: string;
13
+ isHalfScreen: boolean;
14
+ setActionButtons: (actionButtons: JSX.Element) => void;
15
+ }) => JSX.Element;
16
+ }
17
+ export declare const VisualizationPanel: React.NamedExoticComponent<Props>;
18
+ export {};
@@ -0,0 +1,38 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
+ // Copyright 2022 The Parca Authors
14
+ // Licensed under the Apache License, Version 2.0 (the "License");
15
+ // you may not use this file except in compliance with the License.
16
+ // You may obtain a copy of the License at
17
+ //
18
+ // http://www.apache.org/licenses/LICENSE-2.0
19
+ //
20
+ // Unless required by applicable law or agreed to in writing, software
21
+ // distributed under the License is distributed on an "AS IS" BASIS,
22
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ // See the License for the specific language governing permissions and
24
+ // limitations under the License.
25
+ import React, { useState } from 'react';
26
+ import { Icon } from '@iconify/react';
27
+ import cx from 'classnames';
28
+ import { CloseIcon } from '@parca/icons';
29
+ import ViewSelector from './ViewSelector';
30
+ export var VisualizationPanel = React.memo(function VisualizationPanel(_a) {
31
+ var dashboardItem = _a.dashboardItem, index = _a.index, isMultiPanelView = _a.isMultiPanelView, handleClosePanel = _a.handleClosePanel, navigateTo = _a.navigateTo, dragHandleProps = _a.dragHandleProps, getDashboardItemByType = _a.getDashboardItemByType;
32
+ var _b = useState(_jsx(_Fragment, {})), actionButtons = _b[0], setActionButtons = _b[1];
33
+ return (_jsxs(_Fragment, { children: [_jsxs("div", __assign({ className: "w-full flex justify-end pb-2" }, { children: [_jsxs("div", __assign({ className: "w-full flex justify-between items-center" }, { children: [_jsxs("div", __assign({ className: "flex" }, { children: [_jsx("div", __assign({ className: cx(isMultiPanelView ? 'visible' : 'invisible', 'flex items-center') }, dragHandleProps, { children: _jsx(Icon, { className: "text-xl", icon: "material-symbols:drag-indicator" }) })), _jsx(_Fragment, { children: actionButtons })] })), _jsx(ViewSelector, { defaultValue: dashboardItem, navigateTo: navigateTo, position: index })] })), isMultiPanelView && (_jsx("button", __assign({ type: "button", onClick: function () { return handleClosePanel(dashboardItem); }, className: "pl-2" }, { children: _jsx(CloseIcon, {}) })))] })), getDashboardItemByType({
34
+ type: dashboardItem,
35
+ isHalfScreen: isMultiPanelView,
36
+ setActionButtons: setActionButtons,
37
+ })] }));
38
+ });
@@ -33,14 +33,12 @@ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-run
33
33
  // See the License for the specific language governing permissions and
34
34
  // limitations under the License.
35
35
  import { Profiler, useEffect, useMemo, useState } from 'react';
36
- import { Icon } from '@iconify/react';
37
36
  import cx from 'classnames';
38
37
  import { scaleLinear } from 'd3';
39
38
  import { DragDropContext, Draggable, Droppable, } from 'react-beautiful-dnd';
40
39
  import { Button, Card, ConditionalWrapper, KeyDownProvider, useParcaContext, useURLState, } from '@parca/components';
41
40
  import { useContainerDimensions } from '@parca/dynamicsize';
42
41
  import { getNewSpanColor } from '@parca/functions';
43
- import { CloseIcon } from '@parca/icons';
44
42
  import { selectDarkMode, useAppSelector } from '@parca/store';
45
43
  import { Callgraph } from '../';
46
44
  import ProfileIcicleGraph from '../ProfileIcicleGraph';
@@ -49,6 +47,7 @@ import ProfileShareButton from '../components/ProfileShareButton';
49
47
  import useDelayedLoader from '../useDelayedLoader';
50
48
  import FilterByFunctionButton from './FilterByFunctionButton';
51
49
  import ViewSelector from './ViewSelector';
50
+ import { VisualizationPanel } from './VisualizationPanel';
52
51
  function arrayEquals(a, b) {
53
52
  return (Array.isArray(a) &&
54
53
  Array.isArray(b) &&
@@ -63,6 +62,7 @@ export var ProfileView = function (_a) {
63
62
  param: 'dashboard_items',
64
63
  navigateTo: navigateTo,
65
64
  }), rawDashboardItems = _d[0], setDashboardItems = _d[1];
65
+ var currentSearchString = useURLState({ param: 'search_string' })[0];
66
66
  var dashboardItems = rawDashboardItems;
67
67
  var isDarkMode = useAppSelector(selectDarkMode);
68
68
  var isMultiPanelView = dashboardItems.length > 1;
@@ -97,19 +97,19 @@ export var ProfileView = function (_a) {
97
97
  var minColor = scaleLinear([isDarkMode ? 'black' : 'white', maxColor])(0.3);
98
98
  var colorRange = [minColor, maxColor];
99
99
  var getDashboardItemByType = function (_a) {
100
- var type = _a.type, isHalfScreen = _a.isHalfScreen;
100
+ var type = _a.type, isHalfScreen = _a.isHalfScreen, setActionButtons = _a.setActionButtons;
101
101
  switch (type) {
102
102
  case 'icicle': {
103
103
  return (flamegraphData === null || flamegraphData === void 0 ? void 0 : flamegraphData.data) != null ? (_jsx(ConditionalWrapper, __assign({ condition: (perf === null || perf === void 0 ? void 0 : perf.onRender) != null, WrapperComponent: Profiler, wrapperProps: {
104
104
  id: 'icicleGraph',
105
105
  onRender: perf === null || perf === void 0 ? void 0 : perf.onRender,
106
- } }, { children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, graph: flamegraphData.data, sampleUnit: sampleUnit, onContainerResize: onFlamegraphContainerResize, navigateTo: navigateTo, loading: flamegraphData.loading }) }))) : (_jsx(_Fragment, { children: " " }));
106
+ } }, { children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, graph: flamegraphData.data, sampleUnit: sampleUnit, onContainerResize: onFlamegraphContainerResize, navigateTo: navigateTo, loading: flamegraphData.loading, setActionButtons: setActionButtons }) }))) : (_jsx(_Fragment, { children: " " }));
107
107
  }
108
108
  case 'callgraph': {
109
109
  return (callgraphData === null || callgraphData === void 0 ? void 0 : callgraphData.data) != null && (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) !== undefined ? (_jsx(Callgraph, { graph: callgraphData.data, sampleUnit: sampleUnit, width: isHalfScreen ? (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) / 2 : dimensions === null || dimensions === void 0 ? void 0 : dimensions.width, colorRange: colorRange })) : (_jsx(_Fragment, {}));
110
110
  }
111
111
  case 'table': {
112
- return topTableData != null ? (_jsx(TopTable, { loading: topTableData.loading, data: topTableData.data, sampleUnit: sampleUnit, navigateTo: navigateTo })) : (_jsx(_Fragment, {}));
112
+ return topTableData != null ? (_jsx(TopTable, { loading: topTableData.loading, data: topTableData.data, sampleUnit: sampleUnit, navigateTo: navigateTo, setActionButtons: setActionButtons, currentSearchString: currentSearchString })) : (_jsx(_Fragment, {}));
113
113
  }
114
114
  default: {
115
115
  return _jsx(_Fragment, {});
@@ -135,10 +135,6 @@ export var ProfileView = function (_a) {
135
135
  onDownloadPProf();
136
136
  } }, { children: "Download pprof" }))] })), _jsx(FilterByFunctionButton, { navigateTo: navigateTo })] })), _jsx("div", __assign({ className: "flex ml-auto gap-2" }, { children: _jsx(ViewSelector, { defaultValue: "", navigateTo: navigateTo, position: -1, placeholderText: "Add panel...", primary: true, addView: true, disabled: isMultiPanelView || dashboardItems.length < 1 }) }))] })), isLoaderVisible ? (_jsx(_Fragment, { children: loader })) : (_jsx(DragDropContext, __assign({ onDragEnd: onDragEnd }, { children: _jsx("div", __assign({ className: "w-full", ref: ref }, { children: _jsx(Droppable, __assign({ droppableId: "droppable", direction: "horizontal" }, { children: function (provided) { return (_jsx("div", __assign({ ref: provided.innerRef, className: "flex space-x-4 justify-between w-full" }, provided.droppableProps, { children: dashboardItems.map(function (dashboardItem, index) {
137
137
  return (_jsx(Draggable, __assign({ draggableId: dashboardItem, index: index, isDragDisabled: !isMultiPanelView }, { children: function (provided, snapshot) { return (_createElement("div", __assign({ ref: provided.innerRef }, provided.draggableProps, { key: dashboardItem, className: cx('border dark:bg-gray-700 rounded border-gray-300 dark:border-gray-500 p-3', isMultiPanelView ? 'w-1/2' : 'w-full', snapshot.isDragging ? 'bg-gray-200' : 'bg-white') }),
138
- _jsxs("div", __assign({ className: "w-full flex justify-end pb-2" }, { children: [_jsxs("div", __assign({ className: "w-full flex justify-between" }, { children: [_jsx("div", __assign({ className: cx(isMultiPanelView ? 'visible' : 'invisible', 'flex items-center') }, provided.dragHandleProps, { children: _jsx(Icon, { className: "text-xl", icon: "material-symbols:drag-indicator" }) })), _jsx(ViewSelector, { defaultValue: dashboardItem, navigateTo: navigateTo, position: index })] })), isMultiPanelView && (_jsx("button", __assign({ type: "button", onClick: function () { return handleClosePanel(dashboardItem); }, className: "pl-2" }, { children: _jsx(CloseIcon, {}) })))] })),
139
- getDashboardItemByType({
140
- type: dashboardItem,
141
- isHalfScreen: isMultiPanelView,
142
- }))); } }), dashboardItem));
138
+ _jsx(VisualizationPanel, { handleClosePanel: handleClosePanel, isMultiPanelView: isMultiPanelView, dashboardItem: dashboardItem, getDashboardItemByType: getDashboardItemByType, dragHandleProps: provided.dragHandleProps, navigateTo: navigateTo, index: index }))); } }), dashboardItem));
143
139
  }) }))); } })) })) })))] }) }) })) }));
144
140
  };
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import { Top, TopNodeMeta } from '@parca/client';
2
3
  import { type NavigateFunction } from '@parca/functions';
3
4
  interface TopTableProps {
@@ -5,7 +6,9 @@ interface TopTableProps {
5
6
  data?: Top;
6
7
  sampleUnit: string;
7
8
  navigateTo?: NavigateFunction;
9
+ currentSearchString?: string;
10
+ setActionButtons?: (buttons: JSX.Element) => void;
8
11
  }
9
12
  export declare const RowLabel: (meta: TopNodeMeta | undefined) => string;
10
- export declare const TopTable: ({ data: top, sampleUnit: unit, navigateTo, loading, }: TopTableProps) => JSX.Element;
13
+ export declare const TopTable: React.NamedExoticComponent<TopTableProps>;
11
14
  export default TopTable;
@@ -9,7 +9,7 @@ var __assign = (this && this.__assign) || function () {
9
9
  };
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
12
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
13
13
  // Copyright 2022 The Parca Authors
14
14
  // Licensed under the Apache License, Version 2.0 (the "License");
15
15
  // you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
22
22
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
23
  // See the License for the specific language governing permissions and
24
24
  // limitations under the License.
25
- import { useCallback, useMemo } from 'react';
25
+ import React, { useCallback, useEffect, useMemo } from 'react';
26
26
  import { createColumnHelper } from '@tanstack/react-table';
27
27
  import { Button, Table, useURLState } from '@parca/components';
28
28
  import { getLastItem, isSearchMatch, parseParams, valueFormatter, } from '@parca/functions';
@@ -47,12 +47,11 @@ var addPlusSign = function (num) {
47
47
  }
48
48
  return "+".concat(num);
49
49
  };
50
- export var TopTable = function (_a) {
50
+ export var TopTable = React.memo(function TopTable(_a) {
51
51
  var _b;
52
- var top = _a.data, unit = _a.sampleUnit, navigateTo = _a.navigateTo, loading = _a.loading;
52
+ var top = _a.data, unit = _a.sampleUnit, navigateTo = _a.navigateTo, loading = _a.loading, currentSearchString = _a.currentSearchString, setActionButtons = _a.setActionButtons;
53
53
  var router = parseParams(window.location.search);
54
54
  var rawDashboardItems = useURLState({ param: 'dashboard_items' })[0];
55
- var currentSearchString = useURLState({ param: 'search_string' })[0];
56
55
  var rawcompareMode = useURLState({ param: 'compare_a' })[0];
57
56
  var compareMode = rawcompareMode === undefined ? false : rawcompareMode === 'true';
58
57
  var dashboardItems = rawDashboardItems;
@@ -135,12 +134,18 @@ export var TopTable = function (_a) {
135
134
  navigateTo('/', __assign(__assign({}, router), { search_string: '' }), { replace: true });
136
135
  }
137
136
  }, [navigateTo, router]);
137
+ useEffect(function () {
138
+ if (setActionButtons === undefined) {
139
+ return;
140
+ }
141
+ setActionButtons(dashboardItems.length > 1 ? (_jsx(Button, __assign({ color: "neutral", onClick: clearSelection, className: "w-auto", variant: "neutral", disabled: currentSearchString === undefined || currentSearchString.length === 0 }, { children: "Clear selection" }))) : (_jsx(_Fragment, {})));
142
+ }, [dashboardItems, clearSelection, currentSearchString, setActionButtons]);
138
143
  var initialSorting = useMemo(function () {
139
144
  return [{ id: compareMode ? 'diff' : 'cumulative', desc: true }];
140
145
  }, [compareMode]);
141
146
  var total = top != null ? top.list.length : 0;
142
147
  if (total === 0 && !loading)
143
148
  return _jsx(_Fragment, { children: "Profile has no samples" });
144
- return (_jsxs("div", __assign({ className: "relative" }, { children: [dashboardItems.length > 1 && (_jsx("div", __assign({ className: "left-[25px] top-[-45px] absolute" }, { children: _jsx(Button, __assign({ color: "neutral", onClick: clearSelection, className: "w-auto", variant: "neutral", disabled: currentSearchString === undefined || currentSearchString.length === 0 }, { children: "Clear selection" })) }))), _jsx("div", __assign({ className: "w-full font-robotoMono h-[80vh] overflow-scroll" }, { children: _jsx(Table, { data: (_b = top === null || top === void 0 ? void 0 : top.list) !== null && _b !== void 0 ? _b : [], columns: columns, initialSorting: initialSorting, onRowClick: onRowClick, enableHighlighting: enableHighlighting, shouldHighlightRow: shouldHighlightRow, usePointerCursor: dashboardItems.length > 1 }) }))] })));
145
- };
149
+ return (_jsx("div", __assign({ className: "relative" }, { children: _jsx("div", __assign({ className: "w-full font-robotoMono h-[80vh] overflow-scroll" }, { children: _jsx(Table, { data: (_b = top === null || top === void 0 ? void 0 : top.list) !== null && _b !== void 0 ? _b : [], columns: columns, initialSorting: initialSorting, onRowClick: onRowClick, enableHighlighting: enableHighlighting, shouldHighlightRow: shouldHighlightRow, usePointerCursor: dashboardItems.length > 1 }) })) })));
150
+ });
146
151
  export default TopTable;
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- /*! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.invisible{visibility:hidden}.absolute{position:absolute}.relative{position:relative}.-inset-2{bottom:-.5rem;left:-.5rem;right:-.5rem;top:-.5rem}.left-\[25px\]{left:25px}.left-0{left:0}.top-\[-46px\]{top:-46px}.right-0{right:0}.top-\[-45px\]{top:-45px}.top-\[-48px\]{top:-48px}.top-\[-69px\]{top:-69px}.top-\[-54px\]{top:-54px}.top-\[-70px\]{top:-70px}.z-50{z-index:50}.z-10{z-index:10}.m-auto{margin:auto}.m-0{margin:0}.m-2{margin:.5rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-20{margin-bottom:5rem;margin-top:5rem}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.mt-1{margin-top:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mb-2{margin-bottom:.5rem}.mr-6{margin-right:1.5rem}.mr-3{margin-right:.75rem}.mr-1{margin-right:.25rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-fit{height:-moz-fit-content;height:fit-content}.h-10{height:2.5rem}.h-1{height:.25rem}.h-\[80vh\]{height:80vh}.h-4{height:1rem}.max-h-\[400px\]{max-height:400px}.min-h-52{min-height:13rem}.w-auto{width:auto}.w-full{width:100%}.w-1\/4{width:25%}.w-3\/4{width:75%}.w-\[500px\]{width:500px}.w-40{width:10rem}.w-2\/5{width:40%}.w-1\/2{width:50%}.w-8{width:2rem}.w-4{width:1rem}.w-16{width:4rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-\[420px\]{width:420px}.min-w-\[300px\]{min-width:300px}.max-w-\[500px\]{max-width:500px}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-grow{flex-grow:1}.table-auto{table-layout:auto}.table-fixed{table-layout:fixed}.translate-y-1{--tw-translate-y:0.25rem}.translate-y-0,.translate-y-1{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0{--tw-translate-y:0px}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-1{gap:.25rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.text-ellipsis{text-overflow:ellipsis}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-none{border-radius:0}.rounded-l{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.rounded-r{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.border{border-width:1px}.border-r-0{border-right-width:0}.border-l-0{border-left-width:0}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-red-400{--tw-border-opacity:1;border-color:rgb(248 113 113/var(--tw-border-opacity))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-indigo-600{--tw-bg-opacity:1;background-color:rgb(79 70 229/var(--tw-bg-opacity))}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.bg-inherit{background-color:inherit}.fill-transparent{fill:transparent}.fill-current{fill:currentColor}.stroke-white{stroke:#fff}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-10{padding:2.5rem}.p-4{padding:1rem}.p-1{padding:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-20{padding-bottom:5rem;padding-top:5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.pr-0{padding-right:0}.pl-3{padding-left:.75rem}.pr-9{padding-right:2.25rem}.pt-2{padding-top:.5rem}.pb-4{padding-bottom:1rem}.pr-2{padding-right:.5rem}.pl-2{padding-left:.5rem}.pb-2{padding-bottom:.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.text-base{font-size:1rem;line-height:1.5rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-semibold{font-weight:600}.font-bold{font-weight:700}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.\!text-indigo-600{--tw-text-opacity:1!important;color:rgb(79 70 229/var(--tw-text-opacity))!important}.opacity-100{opacity:1}.opacity-0{opacity:0}.opacity-90{opacity:.9}.opacity-50{opacity:.5}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\]{--tw-shadow:0 0 10px 2px rgba(0,0,0,.3);--tw-shadow-colored:0 0 10px 2px var(--tw-shadow-color)}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\],.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity))}.ring-opacity-5{--tw-ring-opacity:0.05}.blur{--tw-blur:blur(8px)}.blur,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert:invert(100%)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-150{transition-duration:.15s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-indigo-800:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(55 48 163/var(--tw-ring-opacity))}.group:hover .group-hover\:flex{display:flex}[class~=theme-dark] .dark\:border-gray-500{--tw-border-opacity:1;border-color:rgb(107 114 128/var(--tw-border-opacity))}[class~=theme-dark] .dark\:bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:stroke-gray-700{stroke:#374151}[class~=theme-dark] .dark\:text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-50{--tw-text-opacity:1;color:rgb(249 250 251/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}[class~=theme-dark] .dark\:\!text-indigo-400{--tw-text-opacity:1!important;color:rgb(129 140 248/var(--tw-text-opacity))!important}@media (min-width:640px){.sm\:inline{display:inline}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}
1
+ /*! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.invisible{visibility:hidden}.absolute{position:absolute}.relative{position:relative}.-inset-2{bottom:-.5rem;left:-.5rem;right:-.5rem;top:-.5rem}.left-\[25px\]{left:25px}.left-0{left:0}.top-\[-46px\]{top:-46px}.right-0{right:0}.z-50{z-index:50}.z-10{z-index:10}.m-auto{margin:auto}.m-0{margin:0}.m-2{margin:.5rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-20{margin-bottom:5rem;margin-top:5rem}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.mt-1{margin-top:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mb-2{margin-bottom:.5rem}.mr-6{margin-right:1.5rem}.mr-3{margin-right:.75rem}.mr-1{margin-right:.25rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-fit{height:-moz-fit-content;height:fit-content}.h-10{height:2.5rem}.h-1{height:.25rem}.h-\[80vh\]{height:80vh}.h-4{height:1rem}.max-h-\[400px\]{max-height:400px}.min-h-52{min-height:13rem}.w-auto{width:auto}.w-full{width:100%}.w-1\/4{width:25%}.w-3\/4{width:75%}.w-\[500px\]{width:500px}.w-40{width:10rem}.w-2\/5{width:40%}.w-1\/2{width:50%}.w-8{width:2rem}.w-4{width:1rem}.w-16{width:4rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-\[420px\]{width:420px}.min-w-\[300px\]{min-width:300px}.max-w-\[500px\]{max-width:500px}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-grow{flex-grow:1}.table-auto{table-layout:auto}.table-fixed{table-layout:fixed}.translate-y-1{--tw-translate-y:0.25rem}.translate-y-0,.translate-y-1{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0{--tw-translate-y:0px}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-1{gap:.25rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.text-ellipsis{text-overflow:ellipsis}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-none{border-radius:0}.rounded-l{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.rounded-r{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.border{border-width:1px}.border-r-0{border-right-width:0}.border-l-0{border-left-width:0}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-red-400{--tw-border-opacity:1;border-color:rgb(248 113 113/var(--tw-border-opacity))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-indigo-600{--tw-bg-opacity:1;background-color:rgb(79 70 229/var(--tw-bg-opacity))}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.bg-inherit{background-color:inherit}.fill-transparent{fill:transparent}.fill-current{fill:currentColor}.stroke-white{stroke:#fff}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-10{padding:2.5rem}.p-4{padding:1rem}.p-1{padding:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-20{padding-bottom:5rem;padding-top:5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.pr-0{padding-right:0}.pl-3{padding-left:.75rem}.pr-9{padding-right:2.25rem}.pt-2{padding-top:.5rem}.pb-4{padding-bottom:1rem}.pr-2{padding-right:.5rem}.pl-2{padding-left:.5rem}.pb-2{padding-bottom:.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.text-base{font-size:1rem;line-height:1.5rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-semibold{font-weight:600}.font-bold{font-weight:700}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.\!text-indigo-600{--tw-text-opacity:1!important;color:rgb(79 70 229/var(--tw-text-opacity))!important}.opacity-100{opacity:1}.opacity-0{opacity:0}.opacity-90{opacity:.9}.opacity-50{opacity:.5}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\]{--tw-shadow:0 0 10px 2px rgba(0,0,0,.3);--tw-shadow-colored:0 0 10px 2px var(--tw-shadow-color)}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\],.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity))}.ring-opacity-5{--tw-ring-opacity:0.05}.blur{--tw-blur:blur(8px)}.blur,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert:invert(100%)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-150{transition-duration:.15s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-indigo-800:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(55 48 163/var(--tw-ring-opacity))}.group:hover .group-hover\:flex{display:flex}[class~=theme-dark] .dark\:border-gray-500{--tw-border-opacity:1;border-color:rgb(107 114 128/var(--tw-border-opacity))}[class~=theme-dark] .dark\:bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:stroke-gray-700{stroke:#374151}[class~=theme-dark] .dark\:text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-50{--tw-text-opacity:1;color:rgb(249 250 251/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}[class~=theme-dark] .dark\:\!text-indigo-400{--tw-text-opacity:1!important;color:rgb(129 140 248/var(--tw-text-opacity))!important}@media (min-width:640px){.sm\:inline{display:inline}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.16.122",
3
+ "version": "0.16.123",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@parca/client": "^0.16.63",
@@ -45,5 +45,5 @@
45
45
  "access": "public",
46
46
  "registry": "https://registry.npmjs.org/"
47
47
  },
48
- "gitHead": "c2165c6991e55c1afd7d11e9c797a3de58578959"
48
+ "gitHead": "4b96b1698f421e95a0b6249943140020555936b1"
49
49
  }