@parca/profile 0.16.50 → 0.16.52
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 +8 -0
- package/dist/ProfileTypeSelector/index.d.ts +2 -1
- package/dist/ProfileTypeSelector/index.js +12 -8
- package/dist/ProfileView.d.ts +4 -4
- package/dist/ProfileView.js +4 -4
- package/dist/ProfileViewWithData.js +3 -5
- package/dist/index.d.ts +16 -0
- package/dist/index.js +1 -0
- package/dist/styles.css +1 -1
- package/package.json +16 -8
- package/src/ProfileTypeSelector/index.tsx +17 -12
- package/src/ProfileView.tsx +112 -114
- package/src/ProfileViewWithData.tsx +2 -4
- package/src/index.tsx +20 -0
- package/tailwind.config.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
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.52](https://github.com/parca-dev/parca/compare/ui-v0.16.51...ui-v0.16.52) (2022-10-19)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
10
|
+
## [0.16.51](https://github.com/parca-dev/parca/compare/ui-v0.16.50...ui-v0.16.51) (2022-10-19)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @parca/profile
|
|
13
|
+
|
|
6
14
|
## [0.16.50](https://github.com/parca-dev/parca/compare/ui-v0.16.49...ui-v0.16.50) (2022-10-18)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { ProfileTypesResponse } from '@parca/client';
|
|
2
|
+
import { ProfileType, ProfileTypesResponse } from '@parca/client';
|
|
3
3
|
import { RpcError } from '@protobuf-ts/runtime-rpc';
|
|
4
4
|
interface WellKnownProfile {
|
|
5
5
|
name: string;
|
|
@@ -9,6 +9,7 @@ interface WellKnownProfiles {
|
|
|
9
9
|
[key: string]: WellKnownProfile;
|
|
10
10
|
}
|
|
11
11
|
export declare const wellKnownProfiles: WellKnownProfiles;
|
|
12
|
+
export declare const normalizeProfileTypesData: (types: ProfileType[]) => string[];
|
|
12
13
|
interface Props {
|
|
13
14
|
profileTypesData?: ProfileTypesResponse;
|
|
14
15
|
loading?: boolean;
|
|
@@ -94,8 +94,9 @@ export var wellKnownProfiles = {
|
|
|
94
94
|
};
|
|
95
95
|
function flexibleWellKnownProfileMatching(name) {
|
|
96
96
|
var prefixExcludedName = name.split(':').slice(1).join(':');
|
|
97
|
+
var deltaExcludedName = prefixExcludedName.replace(/:delta$/, '');
|
|
97
98
|
var requiredKey = Object.keys(wellKnownProfiles).find(function (key) {
|
|
98
|
-
if (key.
|
|
99
|
+
if (key.includes(deltaExcludedName)) {
|
|
99
100
|
return true;
|
|
100
101
|
}
|
|
101
102
|
return false;
|
|
@@ -114,19 +115,22 @@ function profileSelectElement(name, flexibleKnownProfilesDetection) {
|
|
|
114
115
|
expanded: (_jsxs(_Fragment, { children: [_jsx("span", { children: title }), _jsx("br", {}), _jsx("span", __assign({ className: "text-xs" }, { children: wellKnown.help }))] })),
|
|
115
116
|
};
|
|
116
117
|
}
|
|
118
|
+
export var normalizeProfileTypesData = function (types) {
|
|
119
|
+
return types
|
|
120
|
+
.map(function (type) {
|
|
121
|
+
return "".concat(type.name, ":").concat(type.sampleType, ":").concat(type.sampleUnit, ":").concat(type.periodType, ":").concat(type.periodUnit).concat(type.delta ? ':delta' : '');
|
|
122
|
+
})
|
|
123
|
+
.sort(function (a, b) {
|
|
124
|
+
return a.localeCompare(b);
|
|
125
|
+
});
|
|
126
|
+
};
|
|
117
127
|
var ProfileTypeSelector = function (_a) {
|
|
118
128
|
var profileTypesData = _a.profileTypesData, _b = _a.loading, loading = _b === void 0 ? false : _b, error = _a.error, selectedKey = _a.selectedKey, onSelection = _a.onSelection, _c = _a.flexibleKnownProfilesDetection, flexibleKnownProfilesDetection = _c === void 0 ? false : _c;
|
|
119
129
|
var profileNames = useMemo(function () {
|
|
120
130
|
return (error === undefined || error == null) &&
|
|
121
131
|
profileTypesData !== undefined &&
|
|
122
132
|
profileTypesData != null
|
|
123
|
-
? profileTypesData.types
|
|
124
|
-
.map(function (type) {
|
|
125
|
-
return "".concat(type.name, ":").concat(type.sampleType, ":").concat(type.sampleUnit, ":").concat(type.periodType, ":").concat(type.periodUnit).concat(type.delta ? ':delta' : '');
|
|
126
|
-
})
|
|
127
|
-
.sort(function (a, b) {
|
|
128
|
-
return a.localeCompare(b);
|
|
129
|
-
})
|
|
133
|
+
? normalizeProfileTypesData(profileTypesData.types)
|
|
130
134
|
: [];
|
|
131
135
|
}, [profileTypesData, error]);
|
|
132
136
|
var profileLabels = profileNames.map(function (name) { return ({
|
package/dist/ProfileView.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ import { QueryServiceClient, Flamegraph, Top, Callgraph } from '@parca/client';
|
|
|
3
3
|
import { ProfileSource } from './ProfileSource';
|
|
4
4
|
import './ProfileView.styles.css';
|
|
5
5
|
declare type NavigateFunction = (path: string, queryParams: any) => void;
|
|
6
|
-
interface FlamegraphData {
|
|
6
|
+
export interface FlamegraphData {
|
|
7
7
|
loading: boolean;
|
|
8
8
|
data?: Flamegraph;
|
|
9
9
|
error?: any;
|
|
10
10
|
}
|
|
11
|
-
interface TopTableData {
|
|
11
|
+
export interface TopTableData {
|
|
12
12
|
loading: boolean;
|
|
13
13
|
data?: Top;
|
|
14
14
|
error?: any;
|
|
@@ -19,11 +19,11 @@ interface CallgraphData {
|
|
|
19
19
|
error?: any;
|
|
20
20
|
}
|
|
21
21
|
export declare type VisualizationType = 'icicle' | 'table' | 'callgraph' | 'both';
|
|
22
|
-
interface ProfileVisState {
|
|
22
|
+
export interface ProfileVisState {
|
|
23
23
|
currentView: VisualizationType;
|
|
24
24
|
setCurrentView: (view: VisualizationType) => void;
|
|
25
25
|
}
|
|
26
|
-
interface ProfileViewProps {
|
|
26
|
+
export interface ProfileViewProps {
|
|
27
27
|
flamegraphData?: FlamegraphData;
|
|
28
28
|
topTableData?: TopTableData;
|
|
29
29
|
callgraphData?: CallgraphData;
|
package/dist/ProfileView.js
CHANGED
|
@@ -104,8 +104,8 @@ export var ProfileView = function (_a) {
|
|
|
104
104
|
var router = parseParams(window.location.search);
|
|
105
105
|
navigateTo('/', __assign(__assign({}, router), { currentProfileView: view }));
|
|
106
106
|
};
|
|
107
|
-
return (_jsx(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
return (_jsx("div", __assign({ className: "py-3" }, { children: _jsx(Card, { children: _jsxs(Card.Body, { children: [_jsxs("div", __assign({ className: "flex py-3 w-full" }, { children: [_jsxs("div", __assign({ className: "w-2/5 flex space-x-4" }, { children: [_jsxs("div", __assign({ className: "flex space-x-1" }, { children: [profileSource != null && queryClient != null ? (_jsx(ProfileShareButton, { queryRequest: profileSource.QueryRequest(), queryClient: queryClient })) : null, _jsx(Button, __assign({ color: "neutral", onClick: function (e) {
|
|
108
|
+
e.preventDefault();
|
|
109
|
+
onDownloadPProf();
|
|
110
|
+
} }, { children: "Download pprof" }))] })), _jsx(SearchNodes, {})] })), _jsxs("div", __assign({ className: "flex ml-auto" }, { children: [_jsx("div", __assign({ className: "mr-3" }, { children: _jsx(Button, __assign({ color: "neutral", onClick: resetIcicleGraph, disabled: curPath.length === 0, className: "whitespace-nowrap text-ellipsis" }, { children: "Reset View" })) })), callgraphEnabled ? (_jsx("div", __assign({ className: "mr-3" }, { children: _jsx(Button, __assign({ variant: "".concat(currentView === 'callgraph' ? 'primary' : 'neutral'), onClick: function () { return switchProfileView('callgraph'); }, className: "whitespace-nowrap text-ellipsis" }, { children: "Call Graph" })) }))) : null, _jsx(Button, __assign({ variant: "".concat(currentView === 'table' ? 'primary' : 'neutral'), className: "items-center rounded-tr-none rounded-br-none w-auto px-8 whitespace-nowrap text-ellipsis no-outline-on-buttons", onClick: function () { return switchProfileView('table'); } }, { children: "Table" })), _jsx(Button, __assign({ variant: "".concat(currentView === 'both' ? 'primary' : 'neutral'), className: "items-center rounded-tl-none rounded-tr-none rounded-bl-none rounded-br-none border-l-0 border-r-0 w-auto px-8 whitespace-nowrap no-outline-on-buttons text-ellipsis", onClick: function () { return switchProfileView('both'); } }, { children: "Both" })), _jsx(Button, __assign({ variant: "".concat(currentView === 'icicle' ? 'primary' : 'neutral'), className: "items-center rounded-tl-none rounded-bl-none w-auto px-8 whitespace-nowrap text-ellipsis no-outline-on-buttons", onClick: function () { return switchProfileView('icicle'); } }, { children: "Icicle Graph" }))] }))] })), _jsxs("div", __assign({ ref: ref, className: "flex space-x-4 justify-between w-full" }, { children: [currentView === 'icicle' && (flamegraphData === null || flamegraphData === void 0 ? void 0 : flamegraphData.data) != null && (_jsx("div", __assign({ className: "w-full" }, { children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, graph: flamegraphData.data, sampleUnit: sampleUnit }) }))), currentView === 'callgraph' && (callgraphData === null || callgraphData === void 0 ? void 0 : callgraphData.data) != null && (_jsx("div", __assign({ className: "w-full" }, { children: (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) !== undefined && (_jsx(CallgraphComponent, { graph: callgraphData.data, sampleUnit: sampleUnit, width: dimensions === null || dimensions === void 0 ? void 0 : dimensions.width })) }))), currentView === 'table' && topTableData != null && (_jsx("div", __assign({ className: "w-full" }, { children: _jsx(TopTable, { data: topTableData.data, sampleUnit: sampleUnit }) }))), currentView === 'both' && (_jsxs(_Fragment, { children: [_jsx("div", __assign({ className: "w-1/2" }, { children: _jsx(TopTable, { data: topTableData === null || topTableData === void 0 ? void 0 : topTableData.data, sampleUnit: sampleUnit }) })), _jsx("div", __assign({ className: "w-1/2" }, { children: flamegraphData != null && (_jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, graph: flamegraphData.data, sampleUnit: sampleUnit })) }))] }))] }))] }) }) })));
|
|
111
111
|
};
|
|
@@ -52,6 +52,7 @@ import { useQuery } from './useQuery';
|
|
|
52
52
|
import { ProfileView, useProfileVisState } from './ProfileView';
|
|
53
53
|
import { downloadPprof } from './utils';
|
|
54
54
|
import { useGrpcMetadata } from '@parca/components';
|
|
55
|
+
import { saveAsBlob } from '@parca/functions';
|
|
55
56
|
export var ProfileViewWithData = function (_a) {
|
|
56
57
|
var _b, _c;
|
|
57
58
|
var queryClient = _a.queryClient, profileSource = _a.profileSource, navigateTo = _a.navigateTo;
|
|
@@ -69,7 +70,7 @@ export var ProfileViewWithData = function (_a) {
|
|
|
69
70
|
}), callgraphLoading = _f.isLoading, callgraphResponse = _f.response, callgraphError = _f.error;
|
|
70
71
|
var sampleUnit = profileSource.ProfileType().sampleUnit;
|
|
71
72
|
var downloadPProfClick = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
72
|
-
var blob,
|
|
73
|
+
var blob, error_1;
|
|
73
74
|
return __generator(this, function (_a) {
|
|
74
75
|
switch (_a.label) {
|
|
75
76
|
case 0:
|
|
@@ -82,10 +83,7 @@ export var ProfileViewWithData = function (_a) {
|
|
|
82
83
|
return [4 /*yield*/, downloadPprof(profileSource.QueryRequest(), queryClient, metadata)];
|
|
83
84
|
case 2:
|
|
84
85
|
blob = _a.sent();
|
|
85
|
-
|
|
86
|
-
link.href = window.URL.createObjectURL(blob);
|
|
87
|
-
link.download = 'profile.pb.gz';
|
|
88
|
-
link.click();
|
|
86
|
+
saveAsBlob(blob, "profile.pb.gz");
|
|
89
87
|
return [3 /*break*/, 4];
|
|
90
88
|
case 3:
|
|
91
89
|
error_1 = _a.sent();
|
package/dist/index.d.ts
CHANGED
|
@@ -2,12 +2,28 @@ import React from 'react';
|
|
|
2
2
|
import type { Props as CallgraphProps } from '@parca/profile/src/Callgraph';
|
|
3
3
|
import ProfileExplorer from './ProfileExplorer';
|
|
4
4
|
import ProfileTypeSelector from './ProfileTypeSelector';
|
|
5
|
+
import type { FlamegraphData, TopTableData } from './ProfileView';
|
|
6
|
+
import { QueryServiceClient } from '@parca/client';
|
|
5
7
|
export * from './IcicleGraph';
|
|
6
8
|
export * from './ProfileIcicleGraph';
|
|
7
9
|
export * from './ProfileSource';
|
|
8
10
|
export * from './ProfileView';
|
|
9
11
|
export * from './ProfileViewWithData';
|
|
10
12
|
export * from './utils';
|
|
13
|
+
export * from './ProfileTypeSelector';
|
|
11
14
|
export type { CallgraphProps };
|
|
12
15
|
declare const Callgraph: React.LazyExoticComponent<({ graph, sampleUnit, width }: CallgraphProps) => JSX.Element>;
|
|
13
16
|
export { Callgraph, ProfileExplorer, ProfileTypeSelector };
|
|
17
|
+
interface GrafanaParcaDataPayload {
|
|
18
|
+
flamegraphData: FlamegraphData;
|
|
19
|
+
topTableData: TopTableData;
|
|
20
|
+
actions: {
|
|
21
|
+
downloadPprof: () => void;
|
|
22
|
+
getQueryClient: () => QueryServiceClient;
|
|
23
|
+
};
|
|
24
|
+
error?: undefined;
|
|
25
|
+
}
|
|
26
|
+
interface GrafanaParcaErrorPayload {
|
|
27
|
+
error: Error;
|
|
28
|
+
}
|
|
29
|
+
export declare type GrafanaParcaData = GrafanaParcaErrorPayload | GrafanaParcaDataPayload;
|
package/dist/index.js
CHANGED
|
@@ -55,6 +55,7 @@ export * from './ProfileSource';
|
|
|
55
55
|
export * from './ProfileView';
|
|
56
56
|
export * from './ProfileViewWithData';
|
|
57
57
|
export * from './utils';
|
|
58
|
+
export * from './ProfileTypeSelector';
|
|
58
59
|
var Callgraph = React.lazy(function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
59
60
|
switch (_a.label) {
|
|
60
61
|
case 0: return [4 /*yield*/, import('@parca/profile/src/Callgraph')];
|
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
/*! tailwindcss v3.1.8 | 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-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%}*,: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}}.absolute{position:absolute}.relative{position:relative}.left-0{left:0}.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}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-20{margin-bottom:5rem;margin-top:5rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mr-3{margin-right:.75rem}.ml-auto{margin-left:auto}.ml-2{margin-left:.5rem}.mr-6{margin-right:1.5rem}.mt-2{margin-top:.5rem}.mt-1{margin-top:.25rem}.mb-2{margin-bottom:.5rem}.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}.h-36{height:9rem}.h-1{height:.25rem}.h-4{height:1rem}.max-h-\[400px\]{max-height:400px}.w-full{width:100%}.w-2\/5{width:40%}.w-auto{width:auto}.w-1\/2{width:50%}.w-\[150px\]{width:150px}.w-1\/5{width:20%}.w-4\/5{width:80%}.w-fit{width:-moz-fit-content;width:fit-content}.w-1\/4{width:25%}.w-3\/4{width:75%}.w-40{width:10rem}.w-8{width:2rem}.w-16{width:4rem}.w-\[420px\]{width:420px}.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-not-allowed{cursor:not-allowed}.cursor-default{cursor:default}.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}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.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))}.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))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(229 231 235/var(--tw-divide-opacity))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-scroll{overflow-x:scroll}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.break-all{word-break:break-all}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded{border-radius:.25rem}.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}.rounded-tr-none{border-top-right-radius:0}.rounded-br-none{border-bottom-right-radius:0}.rounded-tl-none{border-top-left-radius:0}.rounded-bl-none{border-bottom-left-radius:0}.border{border-width:1px}.border-l-0{border-left-width:0}.border-r-0{border-right-width:0}.border-b{border-bottom-width:1px}.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-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-indigo-600{--tw-bg-opacity:1;background-color:rgb(79 70 229/var(--tw-bg-opacity))}.bg-transparent{background-color:transparent}.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-inherit{background-color:inherit}.fill-\[\#161616\]{fill:#161616}.fill-transparent{fill:transparent}.fill-current{fill:currentColor}.p-10{padding:2.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1\.5{padding-bottom:.375rem;padding-top:.375rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-20{padding-bottom:5rem;padding-top:5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-1{padding-left:.25rem;padding-right:.25rem}.pt-2{padding-top:.5rem}.pb-2{padding-bottom:.5rem}.pl-2{padding-left:.5rem}.pr-2{padding-right:.5rem}.pb-4{padding-bottom:1rem}.pl-3{padding-left:.75rem}.pr-9{padding-right:2.25rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.text-xs{font-size:.75rem;line-height:1rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-base{font-size:1rem;line-height:1.5rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.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-gray-100{--tw-text-opacity:1;color:rgb(243 244 246/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-90{opacity:.9}.opacity-100{opacity:1}.opacity-0{opacity:0}.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);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.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)}.hover\:bg-\[\#62626212\]:hover{background-color:#62626212}.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))}.dark .dark\:divide-gray-700>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(55 65 81/var(--tw-divide-opacity))}.dark .dark\:border-gray-500{--tw-border-opacity:1;border-color:rgb(107 114 128/var(--tw-border-opacity))}.dark .dark\:border-gray-600{--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity))}.dark .dark\:bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.dark .dark\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.dark .dark\:bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.dark .dark\:fill-\[\#ffffff\]{fill:#fff}.dark .dark\:text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.dark .dark\:text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.dark .dark\:text-gray-50{--tw-text-opacity:1;color:rgb(249 250 251/var(--tw-text-opacity))}.dark .dark\:\!text-indigo-400{--tw-text-opacity:1!important;color:rgb(129 140 248/var(--tw-text-opacity))!important}.dark .dark\:hover\:bg-\[\#ffffff12\]:hover{background-color:#ffffff12}@media (min-width:640px){.sm\:inline{display:inline}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}
|
|
1
|
+
/*! tailwindcss v3.1.8 | 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-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%}*,: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}}.absolute{position:absolute}.relative{position:relative}.left-0{left:0}.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}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-20{margin-bottom:5rem;margin-top:5rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mr-3{margin-right:.75rem}.ml-auto{margin-left:auto}.ml-2{margin-left:.5rem}.mr-6{margin-right:1.5rem}.mt-2{margin-top:.5rem}.mt-1{margin-top:.25rem}.mb-2{margin-bottom:.5rem}.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}.h-36{height:9rem}.h-1{height:.25rem}.h-4{height:1rem}.max-h-\[400px\]{max-height:400px}.w-full{width:100%}.w-2\/5{width:40%}.w-auto{width:auto}.w-1\/2{width:50%}.w-\[150px\]{width:150px}.w-1\/5{width:20%}.w-4\/5{width:80%}.w-fit{width:-moz-fit-content;width:fit-content}.w-1\/4{width:25%}.w-3\/4{width:75%}.w-40{width:10rem}.w-8{width:2rem}.w-16{width:4rem}.w-\[420px\]{width:420px}.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-not-allowed{cursor:not-allowed}.cursor-default{cursor:default}.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}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.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))}.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))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(229 231 235/var(--tw-divide-opacity))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-scroll{overflow-x:scroll}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.break-all{word-break:break-all}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded{border-radius:.25rem}.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}.rounded-tr-none{border-top-right-radius:0}.rounded-br-none{border-bottom-right-radius:0}.rounded-tl-none{border-top-left-radius:0}.rounded-bl-none{border-bottom-left-radius:0}.border{border-width:1px}.border-l-0{border-left-width:0}.border-r-0{border-right-width:0}.border-b{border-bottom-width:1px}.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-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-indigo-600{--tw-bg-opacity:1;background-color:rgb(79 70 229/var(--tw-bg-opacity))}.bg-transparent{background-color:transparent}.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-inherit{background-color:inherit}.fill-\[\#161616\]{fill:#161616}.fill-transparent{fill:transparent}.fill-current{fill:currentColor}.p-10{padding:2.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1\.5{padding-bottom:.375rem;padding-top:.375rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-20{padding-bottom:5rem;padding-top:5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-1{padding-left:.25rem;padding-right:.25rem}.pt-2{padding-top:.5rem}.pb-2{padding-bottom:.5rem}.pl-2{padding-left:.5rem}.pr-2{padding-right:.5rem}.pb-4{padding-bottom:1rem}.pl-3{padding-left:.75rem}.pr-9{padding-right:2.25rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.text-xs{font-size:.75rem;line-height:1rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-base{font-size:1rem;line-height:1.5rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.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-gray-100{--tw-text-opacity:1;color:rgb(243 244 246/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-90{opacity:.9}.opacity-100{opacity:1}.opacity-0{opacity:0}.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);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.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)}.hover\:bg-\[\#62626212\]:hover{background-color:#62626212}.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))}[class~=theme-dark] .dark\:divide-gray-700>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(55 65 81/var(--tw-divide-opacity))}[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\:border-gray-600{--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-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\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-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\:fill-\[\#ffffff\]{fill:#fff}[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-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-indigo-400{--tw-text-opacity:1!important;color:rgb(129 140 248/var(--tw-text-opacity))!important}[class~=theme-dark] .dark\:hover\:bg-\[\#ffffff12\]:hover{background-color:#ffffff12}@media (min-width:640px){.sm\:inline{display:inline}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}
|
package/package.json
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.52",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@iconify/react": "^3.2.2",
|
|
7
|
-
"@parca/client": "^0.16.
|
|
8
|
-
"@parca/components": "^0.16.
|
|
9
|
-
"@parca/dynamicsize": "^0.16.
|
|
10
|
-
"@parca/functions": "^0.16.
|
|
7
|
+
"@parca/client": "^0.16.51",
|
|
8
|
+
"@parca/components": "^0.16.51",
|
|
9
|
+
"@parca/dynamicsize": "^0.16.51",
|
|
10
|
+
"@parca/functions": "^0.16.51",
|
|
11
11
|
"@parca/parser": "^0.16.49",
|
|
12
12
|
"@parca/store": "^0.16.49",
|
|
13
|
+
"d3": "7.6.1",
|
|
13
14
|
"d3-scale": "^4.0.2",
|
|
14
15
|
"d3-selection": "3.0.0",
|
|
15
|
-
"
|
|
16
|
+
"graphviz-wasm": "3.0.0",
|
|
17
|
+
"konva": "8.3.12",
|
|
18
|
+
"react-copy-to-clipboard": "^5.1.0",
|
|
19
|
+
"react-cytoscapejs": "1.2.1",
|
|
20
|
+
"react-konva": "18.2.1"
|
|
16
21
|
},
|
|
17
22
|
"devDependencies": {
|
|
18
|
-
"@types/
|
|
23
|
+
"@types/cytoscape": "3.19.9",
|
|
24
|
+
"@types/d3": "7.4.0",
|
|
25
|
+
"@types/react-copy-to-clipboard": "5.0.4",
|
|
26
|
+
"@types/react-cytoscapejs": "1.2.2"
|
|
19
27
|
},
|
|
20
28
|
"main": "dist/index.js",
|
|
21
29
|
"scripts": {
|
|
@@ -31,5 +39,5 @@
|
|
|
31
39
|
"access": "public",
|
|
32
40
|
"registry": "https://registry.npmjs.org/"
|
|
33
41
|
},
|
|
34
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "5641bcb39df874b8235c2d0447d22c40bc3fa5dd"
|
|
35
43
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
|
|
14
14
|
import React, {useMemo} from 'react';
|
|
15
|
-
import {ProfileTypesResponse} from '@parca/client';
|
|
15
|
+
import {ProfileType, ProfileTypesResponse} from '@parca/client';
|
|
16
16
|
import {RpcError} from '@protobuf-ts/runtime-rpc';
|
|
17
17
|
import {SelectElement, Select} from '@parca/components';
|
|
18
18
|
|
|
@@ -96,8 +96,9 @@ export const wellKnownProfiles: WellKnownProfiles = {
|
|
|
96
96
|
|
|
97
97
|
function flexibleWellKnownProfileMatching(name: string): WellKnownProfile | undefined {
|
|
98
98
|
const prefixExcludedName = name.split(':').slice(1).join(':');
|
|
99
|
+
const deltaExcludedName = prefixExcludedName.replace(/:delta$/, '');
|
|
99
100
|
const requiredKey = Object.keys(wellKnownProfiles).find(key => {
|
|
100
|
-
if (key.
|
|
101
|
+
if (key.includes(deltaExcludedName)) {
|
|
101
102
|
return true;
|
|
102
103
|
}
|
|
103
104
|
return false;
|
|
@@ -127,6 +128,19 @@ function profileSelectElement(
|
|
|
127
128
|
};
|
|
128
129
|
}
|
|
129
130
|
|
|
131
|
+
export const normalizeProfileTypesData = (types: ProfileType[]): string[] => {
|
|
132
|
+
return types
|
|
133
|
+
.map(
|
|
134
|
+
type =>
|
|
135
|
+
`${type.name}:${type.sampleType}:${type.sampleUnit}:${type.periodType}:${type.periodUnit}${
|
|
136
|
+
type.delta ? ':delta' : ''
|
|
137
|
+
}`
|
|
138
|
+
)
|
|
139
|
+
.sort((a: string, b: string): number => {
|
|
140
|
+
return a.localeCompare(b);
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
|
|
130
144
|
interface Props {
|
|
131
145
|
profileTypesData?: ProfileTypesResponse;
|
|
132
146
|
loading?: boolean;
|
|
@@ -148,16 +162,7 @@ const ProfileTypeSelector = ({
|
|
|
148
162
|
return (error === undefined || error == null) &&
|
|
149
163
|
profileTypesData !== undefined &&
|
|
150
164
|
profileTypesData != null
|
|
151
|
-
? profileTypesData.types
|
|
152
|
-
.map(
|
|
153
|
-
type =>
|
|
154
|
-
`${type.name}:${type.sampleType}:${type.sampleUnit}:${type.periodType}:${
|
|
155
|
-
type.periodUnit
|
|
156
|
-
}${type.delta ? ':delta' : ''}`
|
|
157
|
-
)
|
|
158
|
-
.sort((a: string, b: string): number => {
|
|
159
|
-
return a.localeCompare(b);
|
|
160
|
-
})
|
|
165
|
+
? normalizeProfileTypesData(profileTypesData.types)
|
|
161
166
|
: [];
|
|
162
167
|
}, [profileTypesData, error]);
|
|
163
168
|
|
package/src/ProfileView.tsx
CHANGED
|
@@ -30,13 +30,13 @@ import './ProfileView.styles.css';
|
|
|
30
30
|
|
|
31
31
|
type NavigateFunction = (path: string, queryParams: any) => void;
|
|
32
32
|
|
|
33
|
-
interface FlamegraphData {
|
|
33
|
+
export interface FlamegraphData {
|
|
34
34
|
loading: boolean;
|
|
35
35
|
data?: Flamegraph;
|
|
36
36
|
error?: any;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
interface TopTableData {
|
|
39
|
+
export interface TopTableData {
|
|
40
40
|
loading: boolean;
|
|
41
41
|
data?: Top;
|
|
42
42
|
error?: any;
|
|
@@ -50,12 +50,12 @@ interface CallgraphData {
|
|
|
50
50
|
|
|
51
51
|
export type VisualizationType = 'icicle' | 'table' | 'callgraph' | 'both';
|
|
52
52
|
|
|
53
|
-
interface ProfileVisState {
|
|
53
|
+
export interface ProfileVisState {
|
|
54
54
|
currentView: VisualizationType;
|
|
55
55
|
setCurrentView: (view: VisualizationType) => void;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
interface ProfileViewProps {
|
|
58
|
+
export interface ProfileViewProps {
|
|
59
59
|
flamegraphData?: FlamegraphData;
|
|
60
60
|
topTableData?: TopTableData;
|
|
61
61
|
callgraphData?: CallgraphData;
|
|
@@ -170,136 +170,134 @@ export const ProfileView = ({
|
|
|
170
170
|
};
|
|
171
171
|
|
|
172
172
|
return (
|
|
173
|
-
|
|
174
|
-
<
|
|
175
|
-
<Card>
|
|
176
|
-
<
|
|
177
|
-
<div className="flex
|
|
178
|
-
<div className="
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
/>
|
|
185
|
-
) : null}
|
|
186
|
-
|
|
187
|
-
<Button
|
|
188
|
-
color="neutral"
|
|
189
|
-
onClick={e => {
|
|
190
|
-
e.preventDefault();
|
|
191
|
-
onDownloadPProf();
|
|
192
|
-
}}
|
|
193
|
-
>
|
|
194
|
-
Download pprof
|
|
195
|
-
</Button>
|
|
196
|
-
</div>
|
|
197
|
-
|
|
198
|
-
<SearchNodes />
|
|
199
|
-
</div>
|
|
200
|
-
|
|
201
|
-
<div className="flex ml-auto">
|
|
202
|
-
<div className="mr-3">
|
|
203
|
-
<Button
|
|
204
|
-
color="neutral"
|
|
205
|
-
onClick={resetIcicleGraph}
|
|
206
|
-
disabled={curPath.length === 0}
|
|
207
|
-
className="whitespace-nowrap text-ellipsis"
|
|
208
|
-
>
|
|
209
|
-
Reset View
|
|
210
|
-
</Button>
|
|
211
|
-
</div>
|
|
212
|
-
|
|
213
|
-
{callgraphEnabled ? (
|
|
214
|
-
<div className="mr-3">
|
|
215
|
-
<Button
|
|
216
|
-
variant={`${currentView === 'callgraph' ? 'primary' : 'neutral'}`}
|
|
217
|
-
onClick={() => switchProfileView('callgraph')}
|
|
218
|
-
className="whitespace-nowrap text-ellipsis"
|
|
219
|
-
>
|
|
220
|
-
Call Graph
|
|
221
|
-
</Button>
|
|
222
|
-
</div>
|
|
173
|
+
<div className="py-3">
|
|
174
|
+
<Card>
|
|
175
|
+
<Card.Body>
|
|
176
|
+
<div className="flex py-3 w-full">
|
|
177
|
+
<div className="w-2/5 flex space-x-4">
|
|
178
|
+
<div className="flex space-x-1">
|
|
179
|
+
{profileSource != null && queryClient != null ? (
|
|
180
|
+
<ProfileShareButton
|
|
181
|
+
queryRequest={profileSource.QueryRequest()}
|
|
182
|
+
queryClient={queryClient}
|
|
183
|
+
/>
|
|
223
184
|
) : null}
|
|
224
185
|
|
|
225
186
|
<Button
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
187
|
+
color="neutral"
|
|
188
|
+
onClick={e => {
|
|
189
|
+
e.preventDefault();
|
|
190
|
+
onDownloadPProf();
|
|
191
|
+
}}
|
|
229
192
|
>
|
|
230
|
-
|
|
193
|
+
Download pprof
|
|
231
194
|
</Button>
|
|
195
|
+
</div>
|
|
232
196
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
className="items-center rounded-tl-none rounded-tr-none rounded-bl-none rounded-br-none border-l-0 border-r-0 w-auto px-8 whitespace-nowrap no-outline-on-buttons text-ellipsis"
|
|
236
|
-
onClick={() => switchProfileView('both')}
|
|
237
|
-
>
|
|
238
|
-
Both
|
|
239
|
-
</Button>
|
|
197
|
+
<SearchNodes />
|
|
198
|
+
</div>
|
|
240
199
|
|
|
200
|
+
<div className="flex ml-auto">
|
|
201
|
+
<div className="mr-3">
|
|
241
202
|
<Button
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
203
|
+
color="neutral"
|
|
204
|
+
onClick={resetIcicleGraph}
|
|
205
|
+
disabled={curPath.length === 0}
|
|
206
|
+
className="whitespace-nowrap text-ellipsis"
|
|
245
207
|
>
|
|
246
|
-
|
|
208
|
+
Reset View
|
|
247
209
|
</Button>
|
|
248
210
|
</div>
|
|
211
|
+
|
|
212
|
+
{callgraphEnabled ? (
|
|
213
|
+
<div className="mr-3">
|
|
214
|
+
<Button
|
|
215
|
+
variant={`${currentView === 'callgraph' ? 'primary' : 'neutral'}`}
|
|
216
|
+
onClick={() => switchProfileView('callgraph')}
|
|
217
|
+
className="whitespace-nowrap text-ellipsis"
|
|
218
|
+
>
|
|
219
|
+
Call Graph
|
|
220
|
+
</Button>
|
|
221
|
+
</div>
|
|
222
|
+
) : null}
|
|
223
|
+
|
|
224
|
+
<Button
|
|
225
|
+
variant={`${currentView === 'table' ? 'primary' : 'neutral'}`}
|
|
226
|
+
className="items-center rounded-tr-none rounded-br-none w-auto px-8 whitespace-nowrap text-ellipsis no-outline-on-buttons"
|
|
227
|
+
onClick={() => switchProfileView('table')}
|
|
228
|
+
>
|
|
229
|
+
Table
|
|
230
|
+
</Button>
|
|
231
|
+
|
|
232
|
+
<Button
|
|
233
|
+
variant={`${currentView === 'both' ? 'primary' : 'neutral'}`}
|
|
234
|
+
className="items-center rounded-tl-none rounded-tr-none rounded-bl-none rounded-br-none border-l-0 border-r-0 w-auto px-8 whitespace-nowrap no-outline-on-buttons text-ellipsis"
|
|
235
|
+
onClick={() => switchProfileView('both')}
|
|
236
|
+
>
|
|
237
|
+
Both
|
|
238
|
+
</Button>
|
|
239
|
+
|
|
240
|
+
<Button
|
|
241
|
+
variant={`${currentView === 'icicle' ? 'primary' : 'neutral'}`}
|
|
242
|
+
className="items-center rounded-tl-none rounded-bl-none w-auto px-8 whitespace-nowrap text-ellipsis no-outline-on-buttons"
|
|
243
|
+
onClick={() => switchProfileView('icicle')}
|
|
244
|
+
>
|
|
245
|
+
Icicle Graph
|
|
246
|
+
</Button>
|
|
249
247
|
</div>
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
<div ref={ref} className="flex space-x-4 justify-between w-full">
|
|
251
|
+
{currentView === 'icicle' && flamegraphData?.data != null && (
|
|
252
|
+
<div className="w-full">
|
|
253
|
+
<ProfileIcicleGraph
|
|
254
|
+
curPath={curPath}
|
|
255
|
+
setNewCurPath={setNewCurPath}
|
|
256
|
+
graph={flamegraphData.data}
|
|
257
|
+
sampleUnit={sampleUnit}
|
|
258
|
+
/>
|
|
259
|
+
</div>
|
|
260
|
+
)}
|
|
250
261
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
<
|
|
255
|
-
|
|
256
|
-
setNewCurPath={setNewCurPath}
|
|
257
|
-
graph={flamegraphData.data}
|
|
262
|
+
{currentView === 'callgraph' && callgraphData?.data != null && (
|
|
263
|
+
<div className="w-full">
|
|
264
|
+
{dimensions?.width !== undefined && (
|
|
265
|
+
<CallgraphComponent
|
|
266
|
+
graph={callgraphData.data}
|
|
258
267
|
sampleUnit={sampleUnit}
|
|
268
|
+
width={dimensions?.width}
|
|
259
269
|
/>
|
|
270
|
+
)}
|
|
271
|
+
</div>
|
|
272
|
+
)}
|
|
273
|
+
|
|
274
|
+
{currentView === 'table' && topTableData != null && (
|
|
275
|
+
<div className="w-full">
|
|
276
|
+
<TopTable data={topTableData.data} sampleUnit={sampleUnit} />
|
|
277
|
+
</div>
|
|
278
|
+
)}
|
|
279
|
+
|
|
280
|
+
{currentView === 'both' && (
|
|
281
|
+
<>
|
|
282
|
+
<div className="w-1/2">
|
|
283
|
+
<TopTable data={topTableData?.data} sampleUnit={sampleUnit} />
|
|
260
284
|
</div>
|
|
261
|
-
)}
|
|
262
285
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
286
|
+
<div className="w-1/2">
|
|
287
|
+
{flamegraphData != null && (
|
|
288
|
+
<ProfileIcicleGraph
|
|
289
|
+
curPath={curPath}
|
|
290
|
+
setNewCurPath={setNewCurPath}
|
|
291
|
+
graph={flamegraphData.data}
|
|
268
292
|
sampleUnit={sampleUnit}
|
|
269
|
-
width={dimensions?.width}
|
|
270
293
|
/>
|
|
271
294
|
)}
|
|
272
295
|
</div>
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
)}
|
|
280
|
-
|
|
281
|
-
{currentView === 'both' && (
|
|
282
|
-
<>
|
|
283
|
-
<div className="w-1/2">
|
|
284
|
-
<TopTable data={topTableData?.data} sampleUnit={sampleUnit} />
|
|
285
|
-
</div>
|
|
286
|
-
|
|
287
|
-
<div className="w-1/2">
|
|
288
|
-
{flamegraphData != null && (
|
|
289
|
-
<ProfileIcicleGraph
|
|
290
|
-
curPath={curPath}
|
|
291
|
-
setNewCurPath={setNewCurPath}
|
|
292
|
-
graph={flamegraphData.data}
|
|
293
|
-
sampleUnit={sampleUnit}
|
|
294
|
-
/>
|
|
295
|
-
)}
|
|
296
|
-
</div>
|
|
297
|
-
</>
|
|
298
|
-
)}
|
|
299
|
-
</div>
|
|
300
|
-
</Card.Body>
|
|
301
|
-
</Card>
|
|
302
|
-
</div>
|
|
303
|
-
</>
|
|
296
|
+
</>
|
|
297
|
+
)}
|
|
298
|
+
</div>
|
|
299
|
+
</Card.Body>
|
|
300
|
+
</Card>
|
|
301
|
+
</div>
|
|
304
302
|
);
|
|
305
303
|
};
|
|
@@ -18,6 +18,7 @@ import {ProfileView, useProfileVisState} from './ProfileView';
|
|
|
18
18
|
import {ProfileSource} from './ProfileSource';
|
|
19
19
|
import {downloadPprof} from './utils';
|
|
20
20
|
import {useGrpcMetadata} from '@parca/components';
|
|
21
|
+
import {saveAsBlob} from '@parca/functions';
|
|
21
22
|
|
|
22
23
|
type NavigateFunction = (path: string, queryParams: any) => void;
|
|
23
24
|
|
|
@@ -69,10 +70,7 @@ export const ProfileViewWithData = ({
|
|
|
69
70
|
|
|
70
71
|
try {
|
|
71
72
|
const blob = await downloadPprof(profileSource.QueryRequest(), queryClient, metadata);
|
|
72
|
-
|
|
73
|
-
link.href = window.URL.createObjectURL(blob);
|
|
74
|
-
link.download = 'profile.pb.gz';
|
|
75
|
-
link.click();
|
|
73
|
+
saveAsBlob(blob, `profile.pb.gz`);
|
|
76
74
|
} catch (error) {
|
|
77
75
|
console.error('Error while querying', error);
|
|
78
76
|
}
|
package/src/index.tsx
CHANGED
|
@@ -15,6 +15,8 @@ import React from 'react';
|
|
|
15
15
|
import type {Props as CallgraphProps} from '@parca/profile/src/Callgraph';
|
|
16
16
|
import ProfileExplorer from './ProfileExplorer';
|
|
17
17
|
import ProfileTypeSelector from './ProfileTypeSelector';
|
|
18
|
+
import type {FlamegraphData, TopTableData} from './ProfileView';
|
|
19
|
+
import {QueryServiceClient} from '@parca/client';
|
|
18
20
|
|
|
19
21
|
export * from './IcicleGraph';
|
|
20
22
|
export * from './ProfileIcicleGraph';
|
|
@@ -22,9 +24,27 @@ export * from './ProfileSource';
|
|
|
22
24
|
export * from './ProfileView';
|
|
23
25
|
export * from './ProfileViewWithData';
|
|
24
26
|
export * from './utils';
|
|
27
|
+
export * from './ProfileTypeSelector';
|
|
25
28
|
|
|
26
29
|
export type {CallgraphProps};
|
|
27
30
|
|
|
28
31
|
const Callgraph = React.lazy(async () => await import('@parca/profile/src/Callgraph'));
|
|
29
32
|
|
|
30
33
|
export {Callgraph, ProfileExplorer, ProfileTypeSelector};
|
|
34
|
+
|
|
35
|
+
// Leaving this in here due to lack of a better place to put it.
|
|
36
|
+
interface GrafanaParcaDataPayload {
|
|
37
|
+
flamegraphData: FlamegraphData;
|
|
38
|
+
topTableData: TopTableData;
|
|
39
|
+
actions: {
|
|
40
|
+
downloadPprof: () => void;
|
|
41
|
+
getQueryClient: () => QueryServiceClient;
|
|
42
|
+
};
|
|
43
|
+
error?: undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface GrafanaParcaErrorPayload {
|
|
47
|
+
error: Error;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type GrafanaParcaData = GrafanaParcaErrorPayload | GrafanaParcaDataPayload;
|