@parca/profile 0.16.209 → 0.16.210

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.210 (2023-07-18)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
6
10
  ## [0.16.209](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.208...@parca/profile@0.16.209) (2023-07-17)
7
11
 
8
12
  **Note:** Version bump only for package @parca/profile
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { Table } from 'apache-arrow';
3
+ interface GraphTooltipArrowContentProps {
4
+ table: Table<any>;
5
+ unit: string;
6
+ total: bigint;
7
+ totalUnfiltered: bigint;
8
+ row: number | null;
9
+ isFixed: boolean;
10
+ }
11
+ declare const GraphTooltipArrowContent: ({ table, unit, total, totalUnfiltered, row, isFixed, }: GraphTooltipArrowContentProps) => React.JSX.Element;
12
+ export default GraphTooltipArrowContent;
@@ -0,0 +1,81 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Copyright 2022 The Parca Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { useState } from 'react';
15
+ import { CopyToClipboard } from 'react-copy-to-clipboard';
16
+ import { divide, getLastItem, valueFormatter } from '@parca/utilities';
17
+ import { FIELD_CUMULATIVE, FIELD_DIFF, FIELD_FUNCTION_FILE_NAME, FIELD_FUNCTION_NAME, FIELD_FUNCTION_START_LINE, FIELD_LABELS, FIELD_LOCATION_ADDRESS, FIELD_LOCATION_LINE, FIELD_MAPPING_BUILD_ID, FIELD_MAPPING_FILE, } from '../ProfileIcicleGraph/IcicleGraphArrow';
18
+ import { hexifyAddress, truncateString, truncateStringReverse } from '../utils';
19
+ import { ExpandOnHover } from './ExpandOnHoverValue';
20
+ let timeoutHandle = null;
21
+ const NoData = () => {
22
+ return _jsx("span", { className: "rounded bg-gray-200 px-2 dark:bg-gray-800", children: "Not available" });
23
+ };
24
+ const GraphTooltipArrowContent = ({ table, unit, total, totalUnfiltered, row, isFixed, }) => {
25
+ const [isCopied, setIsCopied] = useState(false);
26
+ if (row === null) {
27
+ return _jsx(_Fragment, {});
28
+ }
29
+ const locationAddress = table.getChild(FIELD_LOCATION_ADDRESS)?.get(row) ?? 0n;
30
+ const functionName = table.getChild(FIELD_FUNCTION_NAME)?.get(row) ?? '';
31
+ const cumulative = table.getChild(FIELD_CUMULATIVE)?.get(row) ?? 0n;
32
+ const diff = table.getChild(FIELD_DIFF)?.get(row) ?? 0n;
33
+ const onCopy = () => {
34
+ setIsCopied(true);
35
+ if (timeoutHandle !== null) {
36
+ clearTimeout(timeoutHandle);
37
+ }
38
+ timeoutHandle = setTimeout(() => setIsCopied(false), 3000);
39
+ };
40
+ const prevValue = cumulative - diff;
41
+ const diffRatio = diff !== 0n ? divide(diff, prevValue) : 0;
42
+ const diffSign = diff > 0 ? '+' : '';
43
+ const diffValueText = diffSign + valueFormatter(diff, unit, 1);
44
+ const diffPercentageText = diffSign + (diffRatio * 100).toFixed(2) + '%';
45
+ const diffText = `${diffValueText} (${diffPercentageText})`;
46
+ const getTextForCumulative = (hoveringNodeCumulative) => {
47
+ const filtered = totalUnfiltered > total
48
+ ? ` / ${(100 * divide(hoveringNodeCumulative, total)).toFixed(2)}% of filtered`
49
+ : '';
50
+ return `${valueFormatter(hoveringNodeCumulative, unit, 2)}
51
+ (${(100 * divide(hoveringNodeCumulative, totalUnfiltered)).toFixed(2)}%${filtered})`;
52
+ };
53
+ return (_jsx("div", { className: `flex text-sm ${isFixed ? 'w-full' : ''}`, children: _jsx("div", { className: `m-auto w-full ${isFixed ? 'w-full' : ''}`, children: _jsxs("div", { className: "min-h-52 flex w-[500px] flex-col justify-between rounded-lg border border-gray-300 bg-gray-50 p-3 shadow-lg dark:border-gray-500 dark:bg-gray-900", children: [_jsx("div", { className: "flex flex-row", children: _jsxs("div", { className: "mx-2", children: [_jsx("div", { className: "flex h-10 items-center break-all font-semibold", children: row === 0 ? (_jsx("p", { children: "root" })) : (_jsx(_Fragment, { children: functionName !== '' ? (_jsx(CopyToClipboard, { onCopy: onCopy, text: functionName, children: _jsx("button", { className: "cursor-pointer text-left", children: functionName }) })) : (_jsx(_Fragment, { children: locationAddress !== 0n ? (_jsx(CopyToClipboard, { onCopy: onCopy, text: hexifyAddress(locationAddress), children: _jsx("button", { className: "cursor-pointer text-left", children: hexifyAddress(locationAddress) }) })) : (_jsx("p", { children: "unknown" })) })) })) }), _jsx("table", { className: "my-2 w-full table-fixed pr-0 text-gray-700 dark:text-gray-300", children: _jsxs("tbody", { children: [_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Cumulative" }), _jsx("td", { className: "w-3/4", children: _jsx(CopyToClipboard, { onCopy: onCopy, text: getTextForCumulative(cumulative), children: _jsx("button", { className: "cursor-pointer", children: getTextForCumulative(cumulative) }) }) })] }), diff !== 0n && (_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Diff" }), _jsx("td", { className: "w-3/4", children: _jsx(CopyToClipboard, { onCopy: onCopy, text: diffText, children: _jsx("button", { className: "cursor-pointer", children: diffText }) }) })] })), _jsx(TooltipMetaInfo, { table: table, row: row, onCopy: onCopy })] }) })] }) }), _jsx("span", { className: "mx-2 block text-xs text-gray-500", children: isCopied ? 'Copied!' : 'Hold shift and click on a value to copy.' })] }) }) }));
54
+ };
55
+ const TooltipMetaInfo = ({ table,
56
+ // total,
57
+ // totalUnfiltered,
58
+ onCopy, row, }) => {
59
+ const mappingFile = table.getChild(FIELD_MAPPING_FILE)?.get(row) ?? '';
60
+ const mappingBuildID = table.getChild(FIELD_MAPPING_BUILD_ID)?.get(row) ?? '';
61
+ const locationAddress = table.getChild(FIELD_LOCATION_ADDRESS)?.get(row) ?? 0n;
62
+ const locationLine = table.getChild(FIELD_LOCATION_LINE)?.get(row) ?? 0n;
63
+ const functionFilename = table.getChild(FIELD_FUNCTION_FILE_NAME)?.get(row) ?? '';
64
+ const functionStartLine = table.getChild(FIELD_FUNCTION_START_LINE)?.get(row) ?? 0n;
65
+ const labelsString = table.getChild(FIELD_LABELS)?.get(row) ?? '{}';
66
+ const getTextForFile = () => {
67
+ if (functionFilename === '')
68
+ return '<unknown>';
69
+ return `${functionFilename} ${locationLine !== 0n
70
+ ? ` +${locationLine.toString()}`
71
+ : `${functionStartLine !== 0n ? ` +${functionStartLine}` : ''}`}`;
72
+ };
73
+ const file = getTextForFile();
74
+ const labels = Object.entries(JSON.parse(labelsString))
75
+ .sort((a, b) => {
76
+ return a[0].localeCompare(b[0]);
77
+ })
78
+ .map((l) => (_jsx("span", { className: "mr-3 inline-block rounded-lg bg-gray-200 px-2 py-1 text-xs font-bold text-gray-700 dark:bg-gray-700 dark:text-gray-400", children: `${l[0]}="${l[1]}"` }, l[0])));
79
+ return (_jsxs(_Fragment, { children: [_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "File" }), _jsx("td", { className: "w-3/4 break-all", children: functionFilename === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: file, children: _jsx("button", { className: "cursor-pointer whitespace-nowrap text-left", children: _jsx(ExpandOnHover, { value: file, displayValue: truncateStringReverse(file, 40) }) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Address" }), _jsx("td", { className: "w-3/4 break-all", children: locationAddress === 0n ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: hexifyAddress(locationAddress), children: _jsx("button", { className: "cursor-pointer", children: hexifyAddress(locationAddress) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Binary" }), _jsx("td", { className: "w-3/4 break-all", children: mappingFile === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: mappingFile, children: _jsx("button", { className: "cursor-pointer", children: getLastItem(mappingFile) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Build Id" }), _jsx("td", { className: "w-3/4 break-all", children: mappingBuildID === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: mappingBuildID, children: _jsx("button", { className: "cursor-pointer", children: truncateString(getLastItem(mappingBuildID), 28) }) })) })] }), labelsString !== '{}' && (_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Labels" }), _jsx("td", { className: "w-3/4 break-all", children: labels })] }))] }));
80
+ };
81
+ export default GraphTooltipArrowContent;
@@ -1,43 +1,11 @@
1
1
  import React from 'react';
2
- import { Table } from 'apache-arrow';
3
- import { CallgraphNode, CallgraphNodeMeta, FlamegraphNode, FlamegraphNodeMeta, FlamegraphRootNode } from '@parca/client';
4
- import { Location, Mapping, Function as ParcaFunction } from '@parca/client/dist/parca/metastore/v1alpha1/metastore';
5
- interface ExtendedCallgraphNodeMeta extends CallgraphNodeMeta {
6
- lineIndex: number;
7
- locationIndex: number;
8
- }
9
- interface HoveringNode extends FlamegraphRootNode, FlamegraphNode, CallgraphNode {
10
- diff: bigint;
11
- meta?: FlamegraphNodeMeta | ExtendedCallgraphNodeMeta;
12
- }
13
2
  interface GraphTooltipProps {
14
- table: Table<any>;
3
+ children: React.ReactNode;
15
4
  x?: number;
16
5
  y?: number;
17
- unit: string;
18
- total: bigint;
19
- totalUnfiltered: bigint;
20
- hoveringNode?: HoveringNode;
21
6
  contextElement: Element | null;
22
7
  isFixed?: boolean;
23
8
  virtualContextElement?: boolean;
24
- strings?: string[];
25
- mappings?: Mapping[];
26
- locations?: Location[];
27
- functions?: ParcaFunction[];
28
- type?: string;
29
9
  }
30
- export declare const GraphTooltipContent: ({ hoveringNode, unit, total, totalUnfiltered, isFixed, strings, mappings, locations, functions, type, }: {
31
- hoveringNode: HoveringNode;
32
- unit: string;
33
- total: bigint;
34
- totalUnfiltered: bigint;
35
- isFixed: boolean;
36
- strings?: string[] | undefined;
37
- mappings?: Mapping[] | undefined;
38
- locations?: Location[] | undefined;
39
- functions?: ParcaFunction[] | undefined;
40
- type?: string | undefined;
41
- }) => React.JSX.Element;
42
- declare const GraphTooltip: ({ table, x, y, unit, total, totalUnfiltered, contextElement, isFixed, virtualContextElement, strings, mappings, locations, functions, type, }: GraphTooltipProps) => React.JSX.Element;
10
+ declare const GraphTooltip: ({ children, x, y, contextElement, isFixed, virtualContextElement, }: GraphTooltipProps) => React.JSX.Element;
43
11
  export default GraphTooltip;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
2
  // Copyright 2022 The Parca Authors
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -11,19 +11,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
11
11
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
- import { useEffect, useMemo, useState } from 'react';
14
+ import { useEffect, useState } from 'react';
15
15
  import { pointer } from 'd3-selection';
16
- import { CopyToClipboard } from 'react-copy-to-clipboard';
17
16
  import { usePopper } from 'react-popper';
18
17
  import { useKeyDown } from '@parca/components';
19
- import { selectHoveringRow, useAppSelector } from '@parca/store';
20
- import { divide, getLastItem, valueFormatter } from '@parca/utilities';
21
- import { hexifyAddress, truncateString, truncateStringReverse } from '../';
22
- import { FIELD_CUMULATIVE, FIELD_DIFF, FIELD_FUNCTION_FILE_NAME, FIELD_FUNCTION_NAME, FIELD_LOCATION_ADDRESS, FIELD_MAPPING_BUILD_ID, FIELD_MAPPING_FILE, } from '../ProfileIcicleGraph/IcicleGraphArrow';
23
- import { ExpandOnHover } from './ExpandOnHoverValue';
24
- const NoData = () => {
25
- return _jsx("span", { className: "rounded bg-gray-200 px-2 dark:bg-gray-800", children: "Not available" });
26
- };
27
18
  const virtualElement = {
28
19
  getBoundingClientRect: () =>
29
20
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
@@ -49,144 +40,7 @@ function generateGetBoundingClientRect(contextElement, x = 0, y = 0) {
49
40
  bottom: domRect.y + y,
50
41
  });
51
42
  }
52
- const TooltipMetaInfo = ({ hoveringNode, onCopy, strings, mappings, locations, functions, type = 'flamegraph', }) => {
53
- // populate meta from the flamegraph metadata tables
54
- if (type === 'flamegraph' &&
55
- locations !== undefined &&
56
- hoveringNode.meta?.locationIndex !== undefined &&
57
- hoveringNode.meta.locationIndex !== 0) {
58
- const location = locations[hoveringNode.meta.locationIndex - 1];
59
- hoveringNode.meta.location = location;
60
- if (location !== undefined) {
61
- if (mappings !== undefined &&
62
- location.mappingIndex !== undefined &&
63
- location.mappingIndex !== 0) {
64
- const mapping = mappings[location.mappingIndex - 1];
65
- if (strings !== undefined && mapping !== undefined) {
66
- mapping.file =
67
- mapping?.fileStringIndex !== undefined ? strings[mapping.fileStringIndex] : '';
68
- mapping.buildId =
69
- mapping?.buildIdStringIndex !== undefined ? strings[mapping.buildIdStringIndex] : '';
70
- }
71
- hoveringNode.meta.mapping = mapping;
72
- }
73
- if (functions !== undefined &&
74
- location.lines !== undefined &&
75
- hoveringNode.meta.lineIndex !== undefined &&
76
- hoveringNode.meta.lineIndex < location.lines.length) {
77
- const func = functions[location.lines[hoveringNode.meta.lineIndex].functionIndex - 1];
78
- if (strings !== undefined) {
79
- func.name = strings[func.nameStringIndex];
80
- func.systemName = strings[func.systemNameStringIndex];
81
- func.filename = strings[func.filenameStringIndex];
82
- }
83
- hoveringNode.meta.function = func;
84
- }
85
- }
86
- }
87
- const getTextForFile = (hoveringNode) => {
88
- if (hoveringNode.meta?.function == null)
89
- return '<unknown>';
90
- return `${hoveringNode.meta.function.filename} ${hoveringNode.meta.line?.line !== undefined && hoveringNode.meta.line?.line !== 0n
91
- ? ` +${hoveringNode.meta.line.line.toString()}`
92
- : `${hoveringNode.meta.function?.startLine !== undefined &&
93
- hoveringNode.meta.function?.startLine !== 0n
94
- ? ` +${hoveringNode.meta.function.startLine}`
95
- : ''}`}`;
96
- };
97
- const file = getTextForFile(hoveringNode);
98
- return (_jsxs(_Fragment, { children: [_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "File" }), _jsx("td", { className: "w-3/4 break-all", children: hoveringNode.meta?.function?.filename == null ||
99
- hoveringNode.meta?.function.filename === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: file, children: _jsx("button", { className: "cursor-pointer whitespace-nowrap text-left", children: _jsx(ExpandOnHover, { value: file, displayValue: truncateStringReverse(file, 40) }) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Address" }), _jsx("td", { className: "w-3/4 break-all", children: hoveringNode.meta?.location?.address == null ||
100
- hoveringNode.meta?.location.address === 0n ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: hexifyAddress(hoveringNode.meta.location.address), children: _jsx("button", { className: "cursor-pointer", children: hexifyAddress(hoveringNode.meta.location.address) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Binary" }), _jsx("td", { className: "w-3/4 break-all", children: hoveringNode.meta?.mapping == null || hoveringNode.meta.mapping.file === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: hoveringNode.meta.mapping.file, children: _jsx("button", { className: "cursor-pointer", children: getLastItem(hoveringNode.meta.mapping.file) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Build Id" }), _jsx("td", { className: "w-3/4 break-all", children: hoveringNode.meta?.mapping == null || hoveringNode.meta?.mapping.buildId === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: hoveringNode.meta.mapping.buildId, children: _jsx("button", { className: "cursor-pointer", children: truncateString(getLastItem(hoveringNode.meta.mapping.buildId), 28) }) })) })] })] }));
101
- };
102
- let timeoutHandle = null;
103
- export const GraphTooltipContent = ({ hoveringNode, unit, total, totalUnfiltered, isFixed, strings, mappings, locations, functions, type = 'flamegraph', }) => {
104
- const [isCopied, setIsCopied] = useState(false);
105
- const onCopy = () => {
106
- setIsCopied(true);
107
- if (timeoutHandle !== null) {
108
- clearTimeout(timeoutHandle);
109
- }
110
- timeoutHandle = setTimeout(() => setIsCopied(false), 3000);
111
- };
112
- const hoveringNodeCumulative = hoveringNode.cumulative;
113
- const diff = hoveringNode.diff;
114
- const prevValue = hoveringNodeCumulative - diff;
115
- const diffRatio = diff !== 0n ? divide(diff, prevValue) : 0;
116
- const diffSign = diff > 0 ? '+' : '';
117
- const diffValueText = diffSign + valueFormatter(diff, unit, 1);
118
- const diffPercentageText = diffSign + (diffRatio * 100).toFixed(2) + '%';
119
- const diffText = `${diffValueText} (${diffPercentageText})`;
120
- const getTextForCumulative = (hoveringNodeCumulative) => {
121
- const filtered = totalUnfiltered > total
122
- ? ` / ${(100 * divide(hoveringNodeCumulative, total)).toFixed(2)}% of filtered`
123
- : '';
124
- return `${valueFormatter(hoveringNodeCumulative, unit, 2)}
125
- (${(100 * divide(hoveringNodeCumulative, totalUnfiltered)).toFixed(2)}%${filtered})`;
126
- };
127
- return (_jsx("div", { className: `flex text-sm ${isFixed ? 'w-full' : ''}`, children: _jsx("div", { className: `m-auto w-full ${isFixed ? 'w-full' : ''}`, children: _jsxs("div", { className: "min-h-52 flex w-[500px] flex-col justify-between rounded-lg border border-gray-300 bg-gray-50 p-3 shadow-lg dark:border-gray-500 dark:bg-gray-900", children: [_jsx("div", { className: "flex flex-row", children: _jsxs("div", { className: "mx-2", children: [_jsx("div", { className: "flex h-10 items-center break-all font-semibold", children: hoveringNode.meta === undefined ? (_jsx("p", { children: "root" })) : (_jsx(_Fragment, { children: hoveringNode.meta.function !== undefined &&
128
- hoveringNode.meta.function.name !== '' ? (_jsx(CopyToClipboard, { onCopy: onCopy, text: hoveringNode.meta.function.name, children: _jsx("button", { className: "cursor-pointer text-left", children: hoveringNode.meta.function.name }) })) : (_jsx(_Fragment, { children: hoveringNode.meta.location !== undefined &&
129
- hoveringNode.meta.location.address !== 0n ? (_jsx(CopyToClipboard, { onCopy: onCopy, text: hexifyAddress(hoveringNode.meta.location.address), children: _jsx("button", { className: "cursor-pointer text-left", children: hexifyAddress(hoveringNode.meta.location.address) }) })) : (_jsx("p", { children: "unknown" })) })) })) }), _jsx("table", { className: "my-2 w-full table-fixed pr-0 text-gray-700 dark:text-gray-300", children: _jsxs("tbody", { children: [_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Cumulative" }), _jsx("td", { className: "w-3/4", children: _jsx(CopyToClipboard, { onCopy: onCopy, text: getTextForCumulative(hoveringNodeCumulative), children: _jsx("button", { className: "cursor-pointer", children: getTextForCumulative(hoveringNodeCumulative) }) }) })] }), hoveringNode.diff !== undefined && diff !== 0n && (_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Diff" }), _jsx("td", { className: "w-3/4", children: _jsx(CopyToClipboard, { onCopy: onCopy, text: diffText, children: _jsx("button", { className: "cursor-pointer", children: diffText }) }) })] })), _jsx(TooltipMetaInfo, { onCopy: onCopy, hoveringNode: hoveringNode, strings: strings, mappings: mappings, locations: locations, functions: functions, type: type })] }) })] }) }), _jsx("span", { className: "mx-2 block text-xs text-gray-500", children: isCopied ? 'Copied!' : 'Hold shift and click on a value to copy.' })] }) }) }));
130
- };
131
- const GraphTooltip = ({ table, x, y, unit, total, totalUnfiltered, contextElement, isFixed = false, virtualContextElement = true, strings, mappings, locations, functions, type = 'flamegraph', }) => {
132
- const hoveringNodeState = useAppSelector(selectHoveringRow);
133
- const hoveringNode = useMemo(() => {
134
- const s = hoveringNodeState;
135
- if (s === undefined) {
136
- return undefined;
137
- }
138
- const mappingFile = table.getChild(FIELD_MAPPING_FILE)?.get(s.row) ?? '';
139
- const mappingBuildID = table.getChild(FIELD_MAPPING_BUILD_ID)?.get(s.row) ?? '';
140
- const locationAddress = table.getChild(FIELD_LOCATION_ADDRESS)?.get(s.row) ?? 0n;
141
- const functionName = table.getChild(FIELD_FUNCTION_NAME)?.get(s.row) ?? '';
142
- const functionFileName = table.getChild(FIELD_FUNCTION_FILE_NAME)?.get(s.row) ?? '';
143
- const cumulative = table.getChild(FIELD_CUMULATIVE)?.get(s.row) ?? 0n;
144
- const diff = table.getChild(FIELD_DIFF)?.get(s.row) ?? 0n;
145
- const fhn = {
146
- id: '',
147
- flat: 0n,
148
- children: [],
149
- cumulative,
150
- diff: diff === null ? 0n : diff,
151
- meta: {
152
- locationIndex: 0,
153
- lineIndex: 0,
154
- mapping: {
155
- id: '',
156
- start: 0n,
157
- limit: 0n,
158
- offset: 0n,
159
- file: mappingFile,
160
- buildId: mappingBuildID,
161
- hasFunctions: false,
162
- hasFilenames: false,
163
- hasLineNumbers: false,
164
- hasInlineFrames: false,
165
- fileStringIndex: 0,
166
- buildIdStringIndex: 0,
167
- },
168
- location: {
169
- id: '',
170
- address: locationAddress,
171
- mappingId: '',
172
- isFolded: false,
173
- lines: [],
174
- mappingIndex: 0,
175
- },
176
- function: {
177
- id: '',
178
- startLine: 0n,
179
- name: functionName,
180
- systemName: '',
181
- filename: functionFileName,
182
- nameStringIndex: 0,
183
- systemNameStringIndex: 0,
184
- filenameStringIndex: 0,
185
- },
186
- },
187
- };
188
- return fhn;
189
- }, [table, hoveringNodeState]);
43
+ const GraphTooltip = ({ children, x, y, contextElement, isFixed = false, virtualContextElement = true, }) => {
190
44
  const [popperElement, setPopperElement] = useState(null);
191
45
  const { styles, attributes, ...popperProps } = usePopper(virtualContextElement ? virtualElement : contextElement, popperElement, {
192
46
  placement: 'bottom-start',
@@ -237,8 +91,6 @@ const GraphTooltip = ({ table, x, y, unit, total, totalUnfiltered, contextElemen
237
91
  contextElement.removeEventListener('mousemove', onMouseMove);
238
92
  };
239
93
  }, [contextElement, popperProps, isShiftDown, x, y]);
240
- if (hoveringNode === undefined || hoveringNode == null)
241
- return _jsx(_Fragment, {});
242
- return isFixed ? (_jsx(GraphTooltipContent, { hoveringNode: hoveringNode, unit: unit, total: total, totalUnfiltered: totalUnfiltered, isFixed: isFixed, type: type })) : (_jsx("div", { ref: setPopperElement, style: styles.popper, ...attributes.popper, children: _jsx(GraphTooltipContent, { hoveringNode: hoveringNode, unit: unit, total: total, totalUnfiltered: totalUnfiltered, isFixed: isFixed, strings: strings, mappings: mappings, locations: locations, functions: functions, type: type }) }));
94
+ return isFixed ? (_jsx(_Fragment, { children: children })) : (_jsx("div", { ref: setPopperElement, style: styles.popper, ...attributes.popper, children: children }));
243
95
  };
244
96
  export default GraphTooltip;
@@ -13,6 +13,7 @@ interface IcicleGraphNodesProps {
13
13
  level: number;
14
14
  curPath: string[];
15
15
  setCurPath: (path: string[]) => void;
16
+ setHoveringRow: (row: number | null) => void;
16
17
  path: string[];
17
18
  xScale: (value: bigint) => number;
18
19
  searchString?: string;
@@ -37,6 +38,7 @@ interface IcicleNodeProps {
37
38
  path: string[];
38
39
  total: bigint;
39
40
  setCurPath: (path: string[]) => void;
41
+ setHoveringRow: (row: number | null) => void;
40
42
  xScale: (value: bigint) => number;
41
43
  isRoot?: boolean;
42
44
  searchString?: string;
@@ -14,13 +14,13 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
14
14
  import React, { useMemo } from 'react';
15
15
  import cx from 'classnames';
16
16
  import { useKeyDown } from '@parca/components';
17
- import { selectBinaries, setHoveringRow, useAppDispatch, useAppSelector } from '@parca/store';
17
+ import { selectBinaries, useAppSelector } from '@parca/store';
18
18
  import { isSearchMatch, scaleLinear } from '@parca/utilities';
19
19
  import { FIELD_CHILDREN, FIELD_CUMULATIVE, FIELD_DIFF, FIELD_FUNCTION_NAME, FIELD_MAPPING_FILE, } from './index';
20
20
  import useNodeColor from './useNodeColor';
21
21
  import { nodeLabel } from './utils';
22
22
  export const RowHeight = 26;
23
- export const IcicleGraphNodes = React.memo(function IcicleGraphNodesNoMemo({ table, childRows, mappingColors, x, y, xScale, total, totalWidth, level, path, setCurPath, curPath, sortBy, searchString, darkMode, compareMode, }) {
23
+ export const IcicleGraphNodes = React.memo(function IcicleGraphNodesNoMemo({ table, childRows, mappingColors, x, y, xScale, total, totalWidth, level, path, setCurPath, setHoveringRow, curPath, sortBy, searchString, darkMode, compareMode, }) {
24
24
  const cumulatives = table.getChild(FIELD_CUMULATIVE);
25
25
  if (childRows === undefined || childRows.length === 0) {
26
26
  return _jsx(_Fragment, {});
@@ -35,7 +35,7 @@ export const IcicleGraphNodes = React.memo(function IcicleGraphNodesNoMemo({ tab
35
35
  const xStart = Math.floor(xScale(childrenCumulative));
36
36
  const c = cumulatives?.get(child);
37
37
  childrenCumulative += c;
38
- childrenElements.push(_jsx(IcicleNode, { table: table, row: child, mappingColors: mappingColors, x: xStart, y: 0, totalWidth: totalWidth, height: RowHeight, path: path, setCurPath: setCurPath, level: level, curPath: curPath, total: total, xScale: xScale, sortBy: sortBy, searchString: searchString, darkMode: darkMode, compareMode: compareMode }, `node-${level}-${i}`));
38
+ childrenElements.push(_jsx(IcicleNode, { table: table, row: child, mappingColors: mappingColors, x: xStart, y: 0, totalWidth: totalWidth, height: RowHeight, path: path, setCurPath: setCurPath, setHoveringRow: setHoveringRow, level: level, curPath: curPath, total: total, xScale: xScale, sortBy: sortBy, searchString: searchString, darkMode: darkMode, compareMode: compareMode }, `node-${level}-${i}`));
39
39
  });
40
40
  return _jsx("g", { transform: `translate(${x}, ${y})`, children: childrenElements });
41
41
  });
@@ -48,9 +48,8 @@ const fadedIcicleRectStyles = {
48
48
  transition: 'opacity .15s linear',
49
49
  opacity: '0.5',
50
50
  };
51
- export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, mappingColors, x, y, height, setCurPath, curPath, level, path, total, totalWidth, xScale, isRoot = false, searchString, sortBy, darkMode, compareMode, }) {
51
+ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, mappingColors, x, y, height, setCurPath, curPath, level, path, total, totalWidth, xScale, isRoot = false, searchString, setHoveringRow, sortBy, darkMode, compareMode, }) {
52
52
  const { isShiftDown } = useKeyDown();
53
- const dispatch = useAppDispatch();
54
53
  // get the columns to read from
55
54
  const mappingColumn = table.getChild(FIELD_MAPPING_FILE);
56
55
  const functionNameColumn = table.getChild(FIELD_FUNCTION_NAME);
@@ -143,12 +142,12 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, map
143
142
  const onMouseEnter = () => {
144
143
  if (isShiftDown)
145
144
  return;
146
- dispatch(setHoveringRow({ row }));
145
+ setHoveringRow(row);
147
146
  };
148
147
  const onMouseLeave = () => {
149
148
  if (isShiftDown)
150
149
  return;
151
- dispatch(setHoveringRow(undefined));
150
+ setHoveringRow(null);
152
151
  };
153
152
  return (_jsxs(_Fragment, { children: [_jsxs("g", { transform: `translate(${x + 1}, ${y + 1})`, style: styles, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: () => {
154
153
  setCurPath(nextPath);
@@ -156,5 +155,5 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, map
156
155
  fill: colorResult,
157
156
  }, className: cx('stroke-white dark:stroke-gray-700', {
158
157
  'opacity-50': isHighlightEnabled && !isHighlighted,
159
- }) }), width > 5 && (_jsx("svg", { width: width - 5, height: height, children: _jsx("text", { x: 5, y: 15, style: { fontSize: '12px' }, children: name }) }))] }), childRows.length > 0 && (_jsx(IcicleGraphNodes, { table: table, row: row, mappingColors: mappingColors, childRows: childRows, x: x, y: RowHeight, xScale: newXScale, total: total, totalWidth: totalWidth, level: nextLevel, path: nextPath, curPath: nextCurPath, setCurPath: setCurPath, searchString: searchString, sortBy: sortBy, darkMode: darkMode, compareMode: compareMode }))] }));
158
+ }) }), width > 5 && (_jsx("svg", { width: width - 5, height: height, children: _jsx("text", { x: 5, y: 15, style: { fontSize: '12px' }, children: name }) }))] }), childRows.length > 0 && (_jsx(IcicleGraphNodes, { table: table, row: row, mappingColors: mappingColors, childRows: childRows, x: x, y: RowHeight, xScale: newXScale, total: total, totalWidth: totalWidth, level: nextLevel, path: nextPath, curPath: nextCurPath, setCurPath: setCurPath, setHoveringRow: setHoveringRow, searchString: searchString, sortBy: sortBy, darkMode: darkMode, compareMode: compareMode }))] }));
160
159
  });
@@ -4,9 +4,12 @@ import { type NavigateFunction } from '@parca/utilities';
4
4
  export declare const FIELD_MAPPING_FILE = "mapping_file";
5
5
  export declare const FIELD_MAPPING_BUILD_ID = "mapping_build_id";
6
6
  export declare const FIELD_LOCATION_ADDRESS = "location_address";
7
+ export declare const FIELD_LOCATION_LINE = "location_line";
7
8
  export declare const FIELD_FUNCTION_NAME = "function_name";
8
9
  export declare const FIELD_FUNCTION_FILE_NAME = "function_file_name";
10
+ export declare const FIELD_FUNCTION_START_LINE = "function_startline";
9
11
  export declare const FIELD_CHILDREN = "children";
12
+ export declare const FIELD_LABELS = "labels";
10
13
  export declare const FIELD_CUMULATIVE = "cumulative";
11
14
  export declare const FIELD_DIFF = "diff";
12
15
  interface IcicleGraphArrowProps {
@@ -16,15 +16,19 @@ import { USER_PREFERENCES, useUserPreference } from '@parca/hooks';
16
16
  import { getColorForFeature, selectDarkMode, setHoveringNode, useAppDispatch, useAppSelector, } from '@parca/store';
17
17
  import { getLastItem, scaleLinear, selectQueryParam, } from '@parca/utilities';
18
18
  import GraphTooltipArrow from '../../GraphTooltipArrow';
19
+ import GraphTooltipArrowContent from '../../GraphTooltipArrow/Content';
19
20
  import ColorStackLegend from './ColorStackLegend';
20
21
  import { IcicleNode, RowHeight } from './IcicleGraphNodes';
21
22
  import { extractFeature } from './utils';
22
23
  export const FIELD_MAPPING_FILE = 'mapping_file';
23
24
  export const FIELD_MAPPING_BUILD_ID = 'mapping_build_id';
24
25
  export const FIELD_LOCATION_ADDRESS = 'location_address';
26
+ export const FIELD_LOCATION_LINE = 'location_line';
25
27
  export const FIELD_FUNCTION_NAME = 'function_name';
26
28
  export const FIELD_FUNCTION_FILE_NAME = 'function_file_name';
29
+ export const FIELD_FUNCTION_START_LINE = 'function_startline';
27
30
  export const FIELD_CHILDREN = 'children';
31
+ export const FIELD_LABELS = 'labels';
28
32
  export const FIELD_CUMULATIVE = 'cumulative';
29
33
  export const FIELD_DIFF = 'diff';
30
34
  export const IcicleGraphArrow = memo(function IcicleGraphArrow({ table, total, filtered, width, setCurPath, curPath, sampleUnit, navigateTo, }) {
@@ -32,6 +36,7 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ table, total, f
32
36
  const [colorProfile] = useUserPreference(USER_PREFERENCES.FLAMEGRAPH_COLOR_PROFILE.key);
33
37
  const isDarkMode = useAppSelector(selectDarkMode);
34
38
  const [height, setHeight] = useState(0);
39
+ const [hoveringRow, setHoveringRow] = useState(null);
35
40
  const sortBy = FIELD_FUNCTION_NAME; // TODO: make this configurable via UI
36
41
  const svg = useRef(null);
37
42
  const ref = useRef(null);
@@ -105,6 +110,6 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ table, total, f
105
110
  if (table.numRows === 0 || width === undefined) {
106
111
  return _jsx(_Fragment, {});
107
112
  }
108
- return (_jsxs("div", { onMouseLeave: () => dispatch(setHoveringNode(undefined)), children: [_jsx(ColorStackLegend, { mappingColors: mappingColors, navigateTo: navigateTo, compareMode: compareMode }), _jsx(GraphTooltipArrow, { table: table, unit: sampleUnit, total: total, totalUnfiltered: total + filtered, contextElement: svg.current }), _jsx("svg", { className: "font-robotoMono", width: width, height: height, preserveAspectRatio: "xMinYMid", ref: svg, children: _jsx("g", { ref: ref, children: _jsx("g", { transform: 'translate(0, 0)', children: _jsx(IcicleNode, { table: table, row: 0, mappingColors: mappingColors, x: 0, y: 0, totalWidth: width, height: RowHeight, setCurPath: setCurPath, curPath: curPath, total: total, xScale: xScale, path: [], level: 0, isRoot: true, searchString: currentSearchString, sortBy: sortBy, darkMode: isDarkMode, compareMode: compareMode }) }) }) })] }));
113
+ return (_jsxs("div", { onMouseLeave: () => dispatch(setHoveringNode(undefined)), children: [_jsx(ColorStackLegend, { mappingColors: mappingColors, navigateTo: navigateTo, compareMode: compareMode }), _jsx(GraphTooltipArrow, { contextElement: svg.current, children: _jsx(GraphTooltipArrowContent, { table: table, row: hoveringRow, isFixed: false, total: total, totalUnfiltered: total + filtered, unit: sampleUnit }) }), _jsx("svg", { className: "font-robotoMono", width: width, height: height, preserveAspectRatio: "xMinYMid", ref: svg, children: _jsx("g", { ref: ref, children: _jsx("g", { transform: 'translate(0, 0)', children: _jsx(IcicleNode, { table: table, row: 0, mappingColors: mappingColors, x: 0, y: 0, totalWidth: width, height: RowHeight, setCurPath: setCurPath, curPath: curPath, total: total, xScale: xScale, path: [], level: 0, isRoot: true, searchString: currentSearchString, setHoveringRow: setHoveringRow, sortBy: sortBy, darkMode: isDarkMode, compareMode: compareMode }) }) }) })] }));
109
114
  });
110
115
  export default IcicleGraphArrow;
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- /*! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;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;font-feature-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}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:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-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{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,: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:#3b82f680;--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{top:-.5rem;right:-.5rem;bottom:-.5rem;left:-.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-2{margin:.5rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-20{margin-top:5rem;margin-bottom:5rem}.my-6{margin-top:1.5rem;margin-bottom: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-full{height:100%}.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-full{width:100%}.w-auto{width:auto}.w-1\/4{width:25%}.w-3\/4{width:75%}.w-\[500px\]{width:500px}.w-40{width:10rem}.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}.\!items-center{align-items:center!important}.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-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.25rem*var(--tw-space-x-reverse));margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.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-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-r{border-top-right-radius:.25rem;border-bottom-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:#0000}.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-top:.5rem;padding-bottom:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-1{padding-top:.25rem;padding-bottom:.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 #0000004d;--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 #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.outline-none{outline:2px solid #0000;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-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);transition-duration:.15s}.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 #0000;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}}@media (min-width:1024px){.lg\:w-1\/2{width:50%}}
1
+ /*! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;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;font-feature-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}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:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-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{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,: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:#3b82f680;--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{top:-.5rem;right:-.5rem;bottom:-.5rem;left:-.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-2{margin:.5rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-20{margin-top:5rem;margin-bottom:5rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.mr-3{margin-right:.75rem}.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-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-full{height:100%}.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-full{width:100%}.w-auto{width:auto}.w-1\/4{width:25%}.w-3\/4{width:75%}.w-\[500px\]{width:500px}.w-40{width:10rem}.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}.\!items-center{align-items:center!important}.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-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.25rem*var(--tw-space-x-reverse));margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.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-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-r{border-top-right-radius:.25rem;border-bottom-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:#0000}.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-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.px-3{padding-left:.75rem;padding-right:.75rem}.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 #0000004d;--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 #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.outline-none{outline:2px solid #0000;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-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);transition-duration:.15s}.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 #0000;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-400{--tw-text-opacity:1;color:rgb(156 163 175/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-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}}@media (min-width:1024px){.lg\:w-1\/2{width:50%}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.16.209",
3
+ "version": "0.16.210",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@parca/client": "^0.16.80",
@@ -47,5 +47,5 @@
47
47
  "access": "public",
48
48
  "registry": "https://registry.npmjs.org/"
49
49
  },
50
- "gitHead": "e81c1b5d981d8f728a23f867bef27b8922b0285b"
50
+ "gitHead": "493361ba379db553041dcf5e4681f9cdd3a30cb3"
51
51
  }