From 34348bc10eb9dbb9a0363d9607a824f4779e4e79 Mon Sep 17 00:00:00 2001 From: zhangzepeng Date: Tue, 5 Dec 2023 17:36:27 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E2=80=98fix=E6=B3=B3=E9=81=93=E6=94=B6?= =?UTF-8?q?=E8=97=8F=E5=88=97=E8=A1=A8=EF=BC=8C=E6=94=B6=E8=97=8FG1?= =?UTF-8?q?=E7=BB=84=E6=95=B0=E6=8D=AE=E5=90=8E=EF=BC=8C=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=AE=9A=E4=BD=8D=E5=88=B0=E4=BA=86G2?= =?UTF-8?q?=E7=BB=84=E5=BA=95=E9=83=A8=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzepeng --- .../base-ui/chart/column/LitChartColumn.ts | 66 +- .../chart/column/LitChartColumnConfig.ts | 14 +- .../base-ui/chart/scatter/LitChartScatter.ts | 546 ----- .../chart/scatter/LitChartScatterConfig.ts | 45 - ide/src/doc/md/quickstart_native_memory.md | 12 +- ...ickstart_Application_operation_skills.html | 6 +- ide/src/doc/quickstart_animation.html | 2 +- ide/src/doc/quickstart_app_startup.html | 2 +- ide/src/doc/quickstart_arkts.html | 4 +- ide/src/doc/quickstart_hilog.html | 2 +- ide/src/doc/quickstart_hisystemevent.html | 2 +- ide/src/doc/quickstart_memory_template.html | 56 +- ide/src/doc/quickstart_native_memory.html | 20 +- ide/src/doc/quickstart_parsing_ability.html | 8 +- .../doc/quickstart_schedulinganalysis.html | 2 +- ide/src/doc/quickstart_taskpool.html | 2 +- ide/src/figures/Allmemory/snativeheaptab.jpg | Bin 24350 -> 0 bytes ide/src/figures/Allmemory/ssampletab.jpg | Bin 62784 -> 122502 bytes ide/src/figures/Allmemory/sstaaticstab.jpg | Bin 52792 -> 99163 bytes ide/src/figures/Hilog/hilogconfig.jpg | Bin 32692 -> 41510 bytes ide/src/trace/SpApplication.ts | 3 +- ide/src/trace/bean/BinderProcessThread.ts | 60 - ide/src/trace/bean/SchedSwitchStruet.ts | 51 - ide/src/trace/bean/ThreadStruct.ts | 1 - ide/src/trace/component/SpHelp.ts | 15 + ide/src/trace/component/SpKeyboard.ts | 6 - ide/src/trace/component/SpQuerySQL.ts | 7 +- ide/src/trace/component/SpSystemTrace.ts | 160 +- .../trace/component/chart/SpAllAppStartups.ts | 141 -- .../trace/component/chart/SpChartManager.ts | 8 - .../trace/component/chart/SpProcessChart.ts | 193 +- .../component/chart/SpSegmentationChart.ts | 443 ---- .../trace/component/setting/SpHilogRecord.ts | 1 + ide/src/trace/component/trace/SpChartList.ts | 3 +- .../trace/component/trace/base/TraceRow.ts | 76 +- .../trace/component/trace/base/TraceSheet.ts | 21 +- .../component/trace/base/TraceSheetConfig.ts | 29 - ide/src/trace/component/trace/base/Utils.ts | 20 +- .../component/trace/sheet/TabPaneCurrent.ts | 9 +- .../trace/sheet/TabPaneCurrentSelection.ts | 58 +- .../sheet/binder/TabPaneBinderDataCut.ts | 781 ------- .../sheet/binder/TabPaneThreadBinders.ts | 180 -- .../sheet/frequsage/TabPaneFreqDataCut.ts | 1795 +++++++++-------- .../trace/sheet/frequsage/TabPaneFreqUsage.ts | 628 +++--- .../sheet/frequsage/TabPaneFreqUsageConfig.ts | 76 - .../sheet/gpufreq/tabPaneGpufreqDataCut.ts | 456 ----- .../sheet/gpufreq/tabPaneGpufreqUsage.ts | 221 -- .../sheet/schedswitch/TabPaneSchedSwitch.ts | 736 ------- .../trace/timer-shaft/TabPaneFlag.ts | 5 +- ide/src/trace/database/SqlLite.ts | 466 +---- .../database/ui-worker/ProcedureWorker.ts | 6 - .../ui-worker/ProcedureWorkerAllAppStartup.ts | 109 - .../ui-worker/ProcedureWorkerCommon.ts | 256 +-- .../ui-worker/ProcedureWorkerFreqExtend.ts | 109 - .../ui-worker/ProcedureWorkerThread.ts | 3 +- .../ui-worker/procedureWorkerBinder.ts | 110 - .../prebuilts/patch_hiperf/hiviewdfx_BUILD.gn | 2 +- 57 files changed, 1643 insertions(+), 6390 deletions(-) delete mode 100644 ide/src/base-ui/chart/scatter/LitChartScatter.ts delete mode 100644 ide/src/base-ui/chart/scatter/LitChartScatterConfig.ts delete mode 100644 ide/src/figures/Allmemory/snativeheaptab.jpg delete mode 100644 ide/src/trace/bean/BinderProcessThread.ts delete mode 100644 ide/src/trace/bean/SchedSwitchStruet.ts delete mode 100644 ide/src/trace/component/chart/SpAllAppStartups.ts delete mode 100644 ide/src/trace/component/chart/SpSegmentationChart.ts delete mode 100644 ide/src/trace/component/trace/sheet/binder/TabPaneBinderDataCut.ts delete mode 100644 ide/src/trace/component/trace/sheet/binder/TabPaneThreadBinders.ts delete mode 100644 ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsageConfig.ts delete mode 100644 ide/src/trace/component/trace/sheet/gpufreq/tabPaneGpufreqDataCut.ts delete mode 100644 ide/src/trace/component/trace/sheet/gpufreq/tabPaneGpufreqUsage.ts delete mode 100644 ide/src/trace/component/trace/sheet/schedswitch/TabPaneSchedSwitch.ts delete mode 100644 ide/src/trace/database/ui-worker/ProcedureWorkerAllAppStartup.ts delete mode 100644 ide/src/trace/database/ui-worker/ProcedureWorkerFreqExtend.ts delete mode 100644 ide/src/trace/database/ui-worker/procedureWorkerBinder.ts diff --git a/ide/src/base-ui/chart/column/LitChartColumn.ts b/ide/src/base-ui/chart/column/LitChartColumn.ts index 19ddfa533..818412eba 100644 --- a/ide/src/base-ui/chart/column/LitChartColumn.ts +++ b/ide/src/base-ui/chart/column/LitChartColumn.ts @@ -207,42 +207,40 @@ export class LitChartColumn extends BaseElement { for (let i = 0; i <= 5; i++) { this.rowLines.push({ y: gap * i, - label: this.litChartColumnCfg.removeUnit === true ? `${maxValue - valGap * i}` : `${getProbablyTime(maxValue - valGap * i)}`, + label: `${getProbablyTime(maxValue - valGap * i)}`, }); } - if (!this.litChartColumnCfg.notSort) { - this.litChartColumnCfg?.data - .sort((a, b) => b[this.litChartColumnCfg!.yField] - a[this.litChartColumnCfg!.yField]); - } - this.litChartColumnCfg?.data.forEach((litChartColumnItem, litChartColumnIndex, array) => { - this.data.push({ - color: this.litChartColumnCfg!.color(litChartColumnItem), - obj: litChartColumnItem, - root: true, - xLabel: litChartColumnItem[this.litChartColumnCfg!.xField], - yLabel: litChartColumnItem[this.litChartColumnCfg!.yField], - bgFrame: { - x: this.offset!.x! + partWidth * litChartColumnIndex, - y: 0, - w: partWidth, - h: partHeight, - }, - centerX: this.offset!.x! + partWidth * litChartColumnIndex + partWidth / 2, - centerY: - partHeight - - (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue + - (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue / 2, - frame: { - x: this.offset!.x! + partWidth * litChartColumnIndex + partWidth / 6, - y: partHeight - (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue, - w: partWidth - partWidth / 3, - h: (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue, - }, - height: 0, - heightStep: Math.ceil((litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue / 60), - process: true, + this.litChartColumnCfg?.data + .sort((a, b) => b[this.litChartColumnCfg!.yField] - a[this.litChartColumnCfg!.yField]) + .forEach((litChartColumnItem, litChartColumnIndex, array) => { + this.data.push({ + color: this.litChartColumnCfg!.color(litChartColumnItem), + obj: litChartColumnItem, + root: true, + xLabel: litChartColumnItem[this.litChartColumnCfg!.xField], + yLabel: litChartColumnItem[this.litChartColumnCfg!.yField], + bgFrame: { + x: this.offset!.x! + partWidth * litChartColumnIndex, + y: 0, + w: partWidth, + h: partHeight, + }, + centerX: this.offset!.x! + partWidth * litChartColumnIndex + partWidth / 2, + centerY: + partHeight - + (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue + + (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue / 2, + frame: { + x: this.offset!.x! + partWidth * litChartColumnIndex + partWidth / 6, + y: partHeight - (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue, + w: partWidth - partWidth / 3, + h: (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue, + }, + height: 0, + heightStep: Math.ceil((litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue / 60), + process: true, + }); }); - }); } else { let reduceGroup = this.litChartColumnCfg.data.reduce((pre, current, index, arr) => { (pre[current[this.litChartColumnCfg!.xField]] = pre[current[this.litChartColumnCfg!.xField]] || []).push( @@ -261,7 +259,7 @@ export class LitChartColumn extends BaseElement { for (let index = 0; index <= 5; index++) { this.rowLines.push({ y: gap * index, - label: `${getProbablyTime(maxValue - valGap * index)}`, + label: `${getProbablyTime(maxValue - valGap * index)} `, }); } Reflect.ownKeys(reduceGroup) diff --git a/ide/src/base-ui/chart/column/LitChartColumnConfig.ts b/ide/src/base-ui/chart/column/LitChartColumnConfig.ts index 0b3283a39..b508e8278 100644 --- a/ide/src/base-ui/chart/column/LitChartColumnConfig.ts +++ b/ide/src/base-ui/chart/column/LitChartColumnConfig.ts @@ -19,16 +19,14 @@ export interface LitChartColumnConfig { xField: string; yField: string; seriesField: string; - notSort?: boolean; - removeUnit?: boolean; color: (a: any) => string; tip: ((a: any) => string) | undefined; hoverHandler?: (no: number) => void; label: - | { - offset: number; - content: (it: any) => string; - } - | undefined - | null; + | { + offset: number; + content: (it: any) => string; + } + | undefined + | null; } diff --git a/ide/src/base-ui/chart/scatter/LitChartScatter.ts b/ide/src/base-ui/chart/scatter/LitChartScatter.ts deleted file mode 100644 index 26d9f3653..000000000 --- a/ide/src/base-ui/chart/scatter/LitChartScatter.ts +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { resizeCanvas } from '../helper.js'; -import { BaseElement, element } from '../../BaseElement.js'; -import { LitChartScatterConfig } from "./LitChartScatterConfig.js"; - -@element('lit-chart-scatter') -export class LitChartScatter extends BaseElement { - private scatterTipEL: HTMLDivElement | null | undefined; - private labelsEL: HTMLDivElement | null | undefined; - canvas: HTMLCanvasElement | undefined | null; - canvas2: HTMLCanvasElement | undefined | null; - ctx: CanvasRenderingContext2D | undefined | null; - originX: number = 0; - finalX: number = 0; - originY: number = 0; - finalY: number = 0; - options: LitChartScatterConfig | undefined; - - set config(LitChartScatterConfig: LitChartScatterConfig) { - this.options = LitChartScatterConfig; - this.init(); - } - init(): void { - if (this.options) { - // 清楚上一次绘制的数据 - this.ctx?.clearRect(0, 0, this.clientWidth, this.clientHeight); - this.drawBackground(); - this.drawScatterChart(this.options); - //使用off-screen-canvas保存绘制的像素点 - this.setOffScreen(); - this.labelsEL!.innerText = this.options.title; - } - } - // 使用离屏技术保存绘制的像素点 - setOffScreen(): void { - this.canvas2 = document.createElement('canvas'); - this.canvas2.height = this.clientHeight; - this.canvas2.width = this.clientWidth; - let context2 = this.canvas2.getContext('2d'); - if (this.canvas?.width != 0 && this.canvas?.height != 0) { - context2!.drawImage(this.canvas!, 0, 0); - } - } - /*绘制渐变色背景*/ - drawBackground(): void { - let w: number = this.clientWidth; - let h: number = this.clientHeight; - let color: CanvasGradient = this.ctx?.createRadialGradient(w / 2, h / 2, 0.2 * w, w / 2, h / 2, 0.5 * w)!; - color?.addColorStop(0, '#eaeaea'); - color?.addColorStop(1, '#ccc'); - if (this.options) { - this.options!.globalGradient = color; - } - this.ctx?.save(); - this.ctx!.fillStyle = color; - this.ctx?.fillRect(0, 0, w, h); - this.ctx?.restore(); - } - /** - * 绘制散点图 - */ - drawScatterChart(options: LitChartScatterConfig): void { - this.drawAxis(options); //绘制坐标轴 - this.drawYLabels(options); //绘制y轴坐标 - this.drawXLabels(options); //绘制x轴坐标 - let drawload: boolean = false; - if (options) { - drawload = options.drawload; - } - if (drawload) { - let load: Array = []; - if (options) { - load = options.load; - this.drawBalanceLine(load);//绘制均衡线 - this.drawLoadLine(load);//绘制最大负载线 - } - } - this.drawData(options);//绘制散点图 - } - /** - * 绘制坐标轴 - */ - drawAxis(options: LitChartScatterConfig): void { - let text: Array = new Array(); - if (options) { - text = options.AxisLabel; - } - this.ctx!.font = "10px KATTI"; - this.ctx!.fillStyle = "#000000"; - this.ctx!.strokeStyle = "#000000"; - // 画x轴 - this.ctx?.beginPath(); - this.ctx?.moveTo(this.originX, this.originY); - this.ctx?.lineTo(this.finalX, this.originY); - this.ctx?.fillText(text[0], this.finalX, this.originY); - this.ctx?.stroke(); - // 画Y轴 - this.ctx?.beginPath(); - this.ctx?.moveTo(this.originX, this.originY); - this.ctx?.lineTo(this.originX, this.finalY); - this.ctx?.fillText(text[1], this.originX - 20, this.finalY - 10); - this.ctx?.stroke(); - } - /** - * 绘制y轴坐标 - */ - drawYLabels(options: LitChartScatterConfig): void { - // 添加原点刻度 - this.ctx!.font = "12px KATTI"; - this.ctx!.fillStyle = "#000000"; - this.ctx!.strokeStyle = "#000000"; - this.ctx?.fillText("0", this.originX - 5, this.originY + 10); - let yAxis: Array = []; - if (options) { - yAxis = options.yAxisLabel; - } - // 画Y轴坐标尺 - for (let i = 0; i < yAxis.length; i++) { - let length1 = ((this.originY - this.finalY) - ((this.originY - this.finalY) % 100)) * (yAxis[i] / yAxis[yAxis.length - 1]); - let length2 = this.originY - length1; - this.ctx?.beginPath(); - this.ctx?.moveTo(this.originX, length2); - this.ctx?.lineTo(this.originX + 5, length2); - this.ctx?.fillText(yAxis[i].toString(), this.originX - 40, length2 + 5); - this.ctx?.stroke(); - } - - } - /** - * 绘制x轴坐标 - */ - drawXLabels(options: LitChartScatterConfig): void { - // 画X轴坐标尺 - this.ctx!.fillStyle = "#000000"; - this.ctx!.strokeStyle = "#000000"; - let xAxis: Array = []; - if (options) { - xAxis = options.xAxisLabel; - } - for (let i = 0; i < xAxis.length; i++) { - let length3 = ((this.finalX - this.originX) - ((this.finalX - this.originX) % 100)) * (xAxis[i] / xAxis[xAxis.length - 1]); - let length4 = this.originX + length3; - this.ctx?.beginPath(); - this.ctx?.moveTo(length4, this.originY); - this.ctx?.lineTo(length4, this.originY - 5); - this.ctx?.fillText(xAxis[i].toString(), length4 - 5, this.originY + 10); - this.ctx?.stroke(); - } - } - - /** - * 绘制数据 - */ - drawData(options: LitChartScatterConfig): void { - let data: Array>> = []; - let yAxis: Array = []; - let xAxis: Array = []; - let colorPool: Array = new Array(); - let colorPoolText: Array = new Array(); - let rectY: number = this.clientHeight * 0.05; - if (options) { - data = options.data; - yAxis = options.yAxisLabel; - xAxis = options.xAxisLabel; - colorPool = options.colorPool(); - colorPoolText = options.colorPoolText(); - options.paintingData = [] - } - let xLength = ((this.finalX - this.originX) - ((this.finalX - this.originX) % 100)); - let yLength = ((this.originY - this.finalY) - ((this.originY - this.finalY) % 100)); - for (let i = 0; i < data.length; i++) { - for (let j = 0; j < data[i].length; j++) { - // 打点x坐标 - let x = this.originX + (data[i][j][0] / xAxis[xAxis.length - 1]) * xLength; - // 打点y坐标 - let y = this.originY - (data[i][j][1] / yAxis[yAxis.length - 1]) * yLength; - let r = 6; - if (i > 0) { - options.paintingData[data[i][j][2] - 1] = { - x, y, r, c: data[i][j], color: colorPool[i] - }; - } else { - options.paintingData.push({ - x, y, r, c: data[i][j], color: colorPool[i] - }); - } - this.drawCycle(x, y, r, 0.8, colorPool[i]); - } - if (data[i].length) { - rectY = rectY + 20; - this.ctx?.fillText(colorPoolText[i] + ": ", this.clientWidth - 70, rectY + 4); - this.drawCycle(this.clientWidth - 20, rectY, 7.5, 0.8, colorPool[i]); - } - } - } - /** - * 画圆点 - */ - drawCycle(x: number, y: number, r: number, transparency: number, color: string): void { - this.ctx!.fillStyle = color; - this.ctx?.beginPath(); - this.ctx!.globalAlpha = transparency; - this.ctx?.arc(x, y, r, 0, Math.PI * 2, true); - this.ctx?.closePath(); - this.ctx?.fill(); - - } - - /** - * 绘制最大负载线 - */ - drawLoadLine(data: Array): void { - let maxXAxis: number = 1; - if (this.options) { - maxXAxis = this.options.xAxisLabel[this.options.xAxisLabel.length - 1]; - } - // data[1]用来标注n Hz负载线 - let addr1: number = this.originX + ((this.finalX - this.originX) - ((this.finalX - this.originX) % 100)) * (data[0] / maxXAxis); - let addr2: number = ((this.originY - this.finalY) - ((this.originY - this.finalY) % 100)) / 60; - let y: number = this.originY; - this.ctx!.strokeStyle = "#ff0000"; - for (let i = 0; i < 60; i++) { - this.ctx?.beginPath(); - this.ctx?.moveTo(addr1, y); - y -= addr2; - this.ctx?.lineTo(addr1, y); - if (i % 2 != 0) { - this.ctx?.stroke(); - - } - } - this.ctx!.font = "10px KATTI"; - this.ctx!.fillStyle = "#ff0000"; - this.ctx?.fillText(data[1] + 'Hz最大负载线', addr1 - 20, this.originY - addr2 * 60 - 15); - this.ctx!.fillStyle = "#000000"; - this.ctx?.fillText('过供给区', addr1 / 2, y + 30); - this.ctx?.fillText('欠供给区', addr1 / 2, this.originY - this.finalY); - this.ctx?.fillText('超负载区', addr1 + 20, (this.finalY + this.originY) / 2); - } - - /** - * 绘制均衡线 - */ - drawBalanceLine(data: Array): void { - let maxXAxis: number = 1; - if (this.options) { - maxXAxis = this.options.xAxisLabel[this.options.xAxisLabel.length - 1]; - } - // data[1]用来标注n Hz均衡线 - let addr1: number = ((this.finalX - this.originX) - ((this.finalX - this.originX) % 100)) * (data[0] / maxXAxis) / 60; - let addr2: number = ((this.originY - this.finalY) - ((this.originY - this.finalY) % 100)) / 60; - let x: number = this.originX; - let y: number = this.originY; - this.ctx!.strokeStyle = "#00ff00"; - for (let i = 0; i < 60; i++) { - this.ctx?.beginPath(); - this.ctx?.moveTo(x, y); - x += addr1; - y -= addr2; - this.ctx?.lineTo(x, y); - if (i % 2 == 0) { - this.ctx?.stroke(); - - } - } - this.ctx?.save(); - this.ctx?.translate(addr1 * 25 + this.originX, addr2 * 40 + this.finalY); - this.ctx!.font = "10px KATTI"; - this.ctx!.fillStyle = "#ff0f00"; - this.ctx?.rotate(-Math.atan(addr2 / addr1)); - this.ctx?.fillText(data[1] + 'Hz均衡线', 0, 0); - this.ctx?.restore(); - } - - /*检测是否hover在散点之上*/ - checkHover(options: LitChartScatterConfig | undefined, pos: Object): Object | boolean { - let data: Array = []; - if (options) { - data = options.paintingData; - } - let found: boolean | Object = false; - for (let i = 0; i < data.length; i++) { - found = false; - // @ts-ignore - if (Math.sqrt(Math.pow(pos.x - data[i].x, 2) + Math.pow(pos.y - data[i].y, 2)) < data[i].r) { - found = data[i]; - break; - } - } - return found; - } - - /*绘制hover状态*/ - paintHover(): void { - let obj: Object | null = this.options!.hoverData; - // @ts-ignore - let x: number = obj?.x; - // @ts-ignore - let y: number = obj?.y; - // @ts-ignore - let r: number = obj?.r; - // @ts-ignore - let c: string = obj?.color; - let step: number = 0.5; - this.ctx!.globalAlpha = 1; - this.ctx!.fillStyle = c; - for (let i = 0; i < 10; i++) { - this.ctx?.beginPath(); - this.ctx?.arc(x, y, r + i * step, 0, 2 * Math.PI, false); - this.ctx?.fill(); - this.ctx?.closePath(); - } - } - //利用离屏canvas恢复hover前的状态 - resetHoverWithOffScreen(): void { - let obj: Object | null = null; - if (this.options) { - obj = this.options.hoverData; - } - if (!obj) return; - // @ts-ignore - let { x, y, r, c, color } = obj; - let step = 0.5; - this.ctx!.globalAlpha = 1; - for (let i = 10; i > 0; i--) { - this.ctx?.save(); - //绘制外圆范围 - this.ctx?.drawImage(this.canvas2!, x - r - 12 * step, y - r - 12 * step, 2 * (r + 12 * step), 2 * (r + 12 * step), x - r - 12 * step, y - r - 12 * step, 2 * (r + 12 * step), 2 * (r + 12 * step)); - //绘制内圆 - this.ctx?.beginPath(); - this.ctx?.arc(x, y, r + i * step, 0, 2 * Math.PI, false); - this.ctx?.closePath(); - this.ctx!.fillStyle = color; - this.ctx!.globalAlpha = 0.8; - //填充内圆 - this.ctx?.fill(); - this.ctx?.restore(); - } - this.options!.hoverData = null; - } - /** - * 显示提示框 - */ - showTip(data: any): void { - this.scatterTipEL!.style.display = 'flex'; - this.scatterTipEL!.style.top = `${data.y - 70}px`; - this.scatterTipEL!.style.left = `${data.x}px`; - this.scatterTipEL!.innerHTML = this.options!.tip(data); - // @ts-ignore - this.options!.hoverEvent('CPU-FREQ', true, data.c[2] - 1); - } - /** - * 隐藏提示框 - */ - hideTip(): void { - this.scatterTipEL!.style.display = 'none'; - if (this.options) { - // @ts-ignore - this.options!.hoverEvent('CPU-FREQ', false); - } - } - - connectedCallback(): void { - super.connectedCallback(); - this.canvas = this.shadowRoot!.querySelector('#canvas'); - this.scatterTipEL = this.shadowRoot!.querySelector('#tip'); - this.ctx = this.canvas!.getContext('2d', { alpha: true }); - this.labelsEL = this.shadowRoot!.querySelector('#shape'); - resizeCanvas(this.canvas!); - this.originX = this.clientWidth * 0.1; - this.originY = this.clientHeight * 0.9; - this.finalX = this.clientWidth; - this.finalY = this.clientHeight * 0.1; - - /*hover效果*/ - this.canvas!.onmousemove = (event) => { - let pos: Object = { - x: event.offsetX, - y: event.offsetY - } - let hoverPoint: Object | boolean = this.checkHover(this.options, pos); - /** - * 如果当前有聚焦点 - */ - if (hoverPoint) { - this.showTip(hoverPoint); - let samePoint: boolean = this.options!.hoverData === hoverPoint ? true : false; - if (!samePoint) { - this.resetHoverWithOffScreen(); - this.options!.hoverData = hoverPoint; - } - this.paintHover(); - } else { - //使用离屏canvas恢复 - this.resetHoverWithOffScreen(); - this.hideTip(); - } - } - } - - initElements(): void { - new ResizeObserver((entries, observer) => { - entries.forEach((it) => { - resizeCanvas(this.canvas!); - this.originX = this.clientWidth * 0.1; - this.originY = this.clientHeight * 0.95; - this.finalX = this.clientWidth * 0.9; - this.finalY = this.clientHeight * 0.1; - this.labelsEL!.innerText = ''; - this.init(); - }); - }).observe(this); - } - - initHtml(): string { - return ` - -
-
- -
-
-
`; - } -} - - - - - - - - - - - - - - - - - - - - - diff --git a/ide/src/base-ui/chart/scatter/LitChartScatterConfig.ts b/ide/src/base-ui/chart/scatter/LitChartScatterConfig.ts deleted file mode 100644 index bb9384ef5..000000000 --- a/ide/src/base-ui/chart/scatter/LitChartScatterConfig.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface LitChartScatterConfig { - // y轴坐标数组 - yAxisLabel: Array; - // x轴坐标数组 - xAxisLabel: Array; - // 坐标轴名称 - AxisLabel: Array; - // 用于判断是否绘制负载线及均衡线 - drawload: boolean; - // 用于存放最大负载线及均衡线的参数值 - load: Array; - // 打点数据 - data: Array>>; - // 用于存放绘图数据 - paintingData: Array; - // 用于存放移入点数据 - hoverData: Object | null; - // 渐变色信息 - globalGradient: CanvasGradient | undefined; - // 颜色池 - colorPool: () => Array; - // 移入事件 - hoverEvent: void; - // 图表名称 - title: string; - // 颜色数据名称 - colorPoolText: () => Array; - // 提示信息 - tip: (a: any) => string; -} \ No newline at end of file diff --git a/ide/src/doc/md/quickstart_native_memory.md b/ide/src/doc/md/quickstart_native_memory.md index f4898b246..d293018d1 100644 --- a/ide/src/doc/md/quickstart_native_memory.md +++ b/ide/src/doc/md/quickstart_native_memory.md @@ -53,14 +53,14 @@ Native Memory是查看内存的分配和释放等情况。 Statistics的Tab页,主要显示了统计明细类型。 ![GitHub Logo](../../figures/NativeMemory/Statistics.jpg) + Memory Type:内存的类型。 -+ Existing:框选区域内申请没有释放的大小。 -+ #Existing:框选区域内申请没有释放的次数。 ++ Exsiting:框选区域内申请没有释放的大小。 ++ #Exsiting:框选区域内申请没有释放的次数。 + Transient:框选区域内释放的大小。 + #Transient:框选区域内释放的次数。 + Total Bytes:框选区间内申请的大小。 + #Total: 框选区间内申请的次数。 + Peak Value: 框选区间内内存申请的峰值。 -+ Existing/Total:框选区间内剩余的内存比上申请的内存,其中浅紫色是框选区间内申请的大小/整个时间轴(申请+释放的总大小),深紫色是框选区间内(申请+释放)的大小/整个时间轴(申请+释放的总大小)。 ++ Exsiting/Total:框选区间内剩余的内存比上申请的内存,其中浅紫色是框选区间内申请的大小/整个时间轴(申请+释放的总大小),深紫色是框选区间内(申请+释放)的大小/整个时间轴(申请+释放的总大小)。 Call Info的Tab页,主要显示了调用树详细类型。 ![GitHub Logo](../../figures/NativeMemory/CallInfo.jpg) @@ -82,15 +82,15 @@ Snapshot List的Tab页,主要显示了各时刻内存的增长的差值。 + Timestamp :时间戳信息。 + Net Growth :自从上次Snapshot的增长量,是计算的分配和释放的。 + Total Growth :自从上次Snapshot的增长量,是计算的每一次分配的。 -+ #Existing :仍然存在的内存数。 ++ #Exsiting :仍然存在的内存数。 ### Native Memory的辅助信息功能 在Call Info和Native Memory的Tab页,点击选中某一行,右边画红线处会显示出该行调用栈的树结构信息。 ![GitHub Logo](../../figures/NativeMemory/nativecallstack.jpg) ### Native Memory详细显示的过滤功能 -点击下方的All Allocations可以对Allocation的lifeSpan进行过滤,有三个选择:All Allocatios,Create & Existing,Create & Destroyed。 +点击下方的All Allocations可以对Allocation的lifeSpan进行过滤,有三个选择:All Allocatios,Create & Exsiting,Create & Destroyed。 ![GitHub Logo](../../figures/NativeMemory/lifespan.jpg) + All Allocations:所有的内存。 -+ Created & Existing:创建且被存活的内存。 ++ Created & Exsiting:创建且被存活的内存。 + Created & Destroyed: 创建且被销毁的内存。 点击下方的All Heap&Anonymous可以对内存类型进行过滤。 ![GitHub Logo](../../figures/NativeMemory/AllocationType.jpg) diff --git a/ide/src/doc/quickstart_Application_operation_skills.html b/ide/src/doc/quickstart_Application_operation_skills.html index 9942e0170..845473d56 100644 --- a/ide/src/doc/quickstart_Application_operation_skills.html +++ b/ide/src/doc/quickstart_Application_operation_skills.html @@ -808,10 +808,10 @@ 导入so以后,在搜索框中输入libnative_hook.z.so,会发现符号化数据已经更新。
GitHub Logo

-

网页链接文件打开接口

+

网页连接文件打开接口

- 网页链接文件打开接口可以在网址后增加文件地址,打开后直接打开trace。
+ 网页连接文件打开接口可以在网址后增加文件地址,打开后直接打开trace。
接口的url路径如下:
GitHub Logo

@@ -866,7 +866,7 @@

单个泳道图显示为多行时可折叠为1行(收藏和非收藏)

- 单个泳道图点击会将泳道图折叠为一行,折叠后的字体是蓝色。
+ 单个泳道图点击会将泳道图折叠为一行,折腾后的字体是蓝色。
GitHub Logo

已支持的泳道图按照模板分类显示,NaitveMemory,Hisysevent,应用内存等

diff --git a/ide/src/doc/quickstart_animation.html b/ide/src/doc/quickstart_animation.html index 29ab5dfdf..93c949f5a 100644 --- a/ide/src/doc/quickstart_animation.html +++ b/ide/src/doc/quickstart_animation.html @@ -801,7 +801,7 @@
  • -Animation effect:动效配置项的总开关。解析时请打开对应的Flags标记(Disabled切换为Enabled)。
    +Animation effect:动效配置项的总开关。
     
diff --git a/ide/src/doc/quickstart_app_startup.html b/ide/src/doc/quickstart_app_startup.html index 36fbd7096..ce0107c86 100644 --- a/ide/src/doc/quickstart_app_startup.html +++ b/ide/src/doc/quickstart_app_startup.html @@ -803,7 +803,7 @@
  • -App startup:配置项的总开关。解析时请打开对应的Flags标记(Disabled切换为Enabled)。
    +App startup:配置项的总开关。
     
diff --git a/ide/src/doc/quickstart_arkts.html b/ide/src/doc/quickstart_arkts.html index f88fdfd48..9edcb0f5e 100644 --- a/ide/src/doc/quickstart_arkts.html +++ b/ide/src/doc/quickstart_arkts.html @@ -797,14 +797,14 @@

Cpuprofiler的抓取配置参数

- 打开Start Ark Ts Record总开关下面的Start cpu profiler开关抓取Cpuprofiler数据。 + 打开Start Ark Ts Record总开关下面的Start cpu profiler开关抓取cpuprofiler数据。
GitHub Logo

Cpuprofiler展示说明

- 将抓取的Cpuprofiler文件导入到SmartPerf中,查看Ts层耗时长的函数和阶段。 + 将抓取的cpuprofiler文件导入到smartperf中,查看Ts层耗时长的函数和阶段。
GitHub Logo

diff --git a/ide/src/doc/quickstart_hilog.html b/ide/src/doc/quickstart_hilog.html index 949612296..7c9528d1a 100644 --- a/ide/src/doc/quickstart_hilog.html +++ b/ide/src/doc/quickstart_hilog.html @@ -799,7 +799,7 @@

Hilog的抓取配置参数

- 打开Hilog开关抓取Hilog数据。
+ 打开Hilog开关抓取taskpool数据。
GitHub Logo

Hilog展示说明

diff --git a/ide/src/doc/quickstart_hisystemevent.html b/ide/src/doc/quickstart_hisystemevent.html index 707ace392..609629f5d 100644 --- a/ide/src/doc/quickstart_hisystemevent.html +++ b/ide/src/doc/quickstart_hisystemevent.html @@ -835,7 +835,7 @@ System Event泳道: 以条状图显示,红色代表后台任务(WORKSCHEDULE
  • -Power泳道:应用各个子类的功耗柱状图、折线图以及应用各个子类绘制的图例,鼠标的悬浮可以显示出各个子类功耗的具体值。
    +Power泳道:应用各个子类的功耗柱状图、折现图以及应用各个子类绘制的图例,鼠标的悬浮可以显示出各个子类功耗的具体值。
     
  • diff --git a/ide/src/doc/quickstart_memory_template.html b/ide/src/doc/quickstart_memory_template.html index 4b4f3cf39..ebbe64ce5 100644 --- a/ide/src/doc/quickstart_memory_template.html +++ b/ide/src/doc/quickstart_memory_template.html @@ -1126,8 +1126,8 @@ MinSize:Gpu内存的最小值。

    VM Tracker下的smaps泳道图的点选和框选功能

    - 点选Dirty,Swapped,RSS,PSS,USS的5个泳道图中任一个显示的都是一样的内容,会显示Smaps Statistic,Smaps - sample,Smaps Comparison,Native Heap的tab页。 + 点选和框选Dirty,Swapped,RSS,PSS,USS的5个泳道图中任一个显示的都是一样的内容,会显示Smaps Statistic和Smaps + sample的tab页。
    Smaps Statistic的tab页展示。
    @@ -1304,60 +1304,10 @@ Protection: 内存块的权限(读写执行执行)。 >

  • -

    - Native Heap的tab页展示。 -
    - GitHub Logo -

    -
      -
    • -
      -TimeStamp: 时间戳信息。
      -
      -
    • -
    • -
      -Total: 该时间点Smaps中type为NATIVE_HEAP的Size。
      -
      -
    • -
    • -
      -RenderServiceCpu:渲染框架数据,计算规则为该时间点上memroy_rs_image表中type!="pixelmap"的所有项累加Size。
      -
      -
    • -
    • -
      -SkiaCpu:渲染框架数据,取该时间点memory_cpu表中total_size的值。
      -
      -
    • -
    • -
      -GLESHostCache: GLES-CPU缓存,取该时间点memory_profile表中total_size之和。
      -
      -
    • -
    • -
      -ProcessCache: Total-RenderServiceCpu-SkiaCpu-GLESHostCache的值。
      -
      -
    • -
    -

    - 框选Dirty,Swapped,RSS,PSS,USS的5个泳道图中任一个显示的都是一样的内容,会显示Smaps Statistic和Smaps - sample的tab页。 -
    - Smaps Statistic的tab页和Smaps sample的tab页展示(同点选)。 -
    -

    VM Tracker下的GPU泳道图展示

    - GPU泳道图分为GL,Skia Gpu Dump Toal,Skia Gpu Dump Window,Skia Gpu Memory泳道图。 + smaps泳道图分为GL,Skia Gpu Dump Toal,Skia Gpu Dump Window,Skia Gpu Memory泳道图。
    GitHub Logo
    diff --git a/ide/src/doc/quickstart_native_memory.html b/ide/src/doc/quickstart_native_memory.html index be0ade86c..34526429a 100644 --- a/ide/src/doc/quickstart_native_memory.html +++ b/ide/src/doc/quickstart_native_memory.html @@ -891,12 +891,12 @@ Memory Type:内存的类型。

  • -Existing:框选区域内申请没有释放的大小。
    +Exsiting:框选区域内申请没有释放的大小。
     
  • -#Existing:框选区域内申请没有释放的次数。
    +#Exsiting:框选区域内申请没有释放的次数。
     
  • @@ -926,7 +926,7 @@ Peak Value: 框选区间内内存申请的峰值。
  • -Existing/Total:框选区间内剩余的内存比上申请的内存,其中浅紫色是框选区间内申请的大小/整个时间轴(申请+释放的总大小),深紫色是框选区间内(申请+释放)的大小/整个时间轴(申请+释放的总大小)。
    +Exsiting/Total:框选区间内剩余的内存比上申请的内存,其中浅紫色是框选区间内申请的大小/整个时间轴(申请+释放的总大小),深紫色是框选区间内(申请+释放)的大小/整个时间轴(申请+释放的总大小)。
     
  • @@ -937,7 +937,7 @@ Existing/Total:框选区间内剩余的内存比上申请的内存,其中浅
    • -Symbol Name:每个内存分配的调用栈。
      +Symble Name:每个内存分配的调用栈。
       
    • @@ -1009,7 +1009,7 @@ Timestamp :时间戳信息。
    • -Net Growth :自从上次Snapshot的增长量,是计算分配和释放的。
      +Net Growth :自从上次Snapshot的增长量,是计算的分配和释放的。
       
    • @@ -1019,7 +1019,7 @@ Total Growth :自从上次Snapshot的增长量,是计算的每一次分配
    • -#Existing  :仍然存在的内存数。
      +#Exsiting  :仍然存在的内存数。
       
    @@ -1032,8 +1032,8 @@ Total Growth :自从上次Snapshot的增长量,是计算的每一次分配

    Native Memory详细显示的过滤功能

    - 点击下方的All Allocations可以对Allocation lifeSpan进行过滤,有三个选择:All Allocations,Created & - Existing,Created & Destroyed。
    + 点击下方的All Allocations可以对Allocation的lifeSpan进行过滤,有三个选择:All Allocatios,Create & + Exsiting,Create & Destroyed。
    GitHub Logo

      @@ -1044,7 +1044,7 @@ Total Growth :自从上次Snapshot的增长量,是计算的每一次分配
    • - Created & Existing:创建且存活的内存。
      + Created & Exsiting:创建且被存活的内存。
       
    • @@ -1054,7 +1054,7 @@ Total Growth :自从上次Snapshot的增长量,是计算的每一次分配

    - 点击下方的All Heap&Anonymous VM可以对内存类型进行过滤。
    + 点击下方的All Heap&Anonymous可以对内存类型进行过滤。
    GitHub Logo

    `; }, }, + { + title: '进程smaps抓取和展示说明', + icon: '', + clickHandler: function (item: MenuItem) { + SpStatisticsHttpUtil.addOrdinaryVisitAction({ + event: 'smaps', + action: 'help_doc', + }); + that.appContent!.innerHTML = + ' 展示快捷方式 - - -
    v
    - - 展示/隐藏Vsync信号 - diff --git a/ide/src/trace/component/SpQuerySQL.ts b/ide/src/trace/component/SpQuerySQL.ts index 4642ff926..64ef9b8d9 100644 --- a/ide/src/trace/component/SpQuerySQL.ts +++ b/ide/src/trace/component/SpQuerySQL.ts @@ -168,7 +168,7 @@ export class SpQuerySQL extends BaseElement { if (resultList && resultList.length > 0) { this.statDataArray = resultList; this.keyList = Object.keys(resultList[0]); - this.querySize!.textContent = `Query result - ${this.statDataArray.length} counts.`; + this.querySize!.textContent = `Query result - ${this.statDataArray.length} counts.` + `(${sql})`; this.initDataElement(); this.response!.appendChild(this.queryTableEl!); this.setPageNationTableEl(); @@ -179,7 +179,7 @@ export class SpQuerySQL extends BaseElement { } }, 300); } else { - this.querySize!.textContent = `Query result - ${this.statDataArray.length} counts.`; + this.querySize!.textContent = `Query result - ${this.statDataArray.length} counts.` + `(${sql})`; this.progressLoad!.loading = false; } }); @@ -414,6 +414,9 @@ export class SpQuerySQL extends BaseElement { line-height: 20px; font-weight: 400; text-align: left; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } #response-json{ margin-top: 20px; diff --git a/ide/src/trace/component/SpSystemTrace.ts b/ide/src/trace/component/SpSystemTrace.ts index d2941ceb3..2de349931 100644 --- a/ide/src/trace/component/SpSystemTrace.ts +++ b/ide/src/trace/component/SpSystemTrace.ts @@ -84,7 +84,6 @@ import { TabPaneCurrentSelection } from './trace/sheet/TabPaneCurrentSelection.j import { SpChartList } from './trace/SpChartList.js'; import './trace/SpChartList.js'; import { AppStartupStruct } from '../database/ui-worker/ProcedureWorkerAppStartup.js'; -import { AllAppStartupStruct } from '../database/ui-worker/ProcedureWorkerAllAppStartup.js'; import { SoStruct } from '../database/ui-worker/ProcedureWorkerSoInit.js'; import { TabPaneTaskFrames } from './trace/sheet/task/TabPaneTaskFrames.js'; import { FlagsConfig } from './SpFlags.js'; @@ -108,7 +107,6 @@ import { type HiSysEventStruct } from '../database/ui-worker/ProcedureWorkerHiSy import { InitAnalysis } from '../database/logic-worker/ProcedureLogicWorkerCommon.js'; import { type SpKeyboard } from '../component/SpKeyboard.js'; import { drawVSync, enableVSync, setVSyncDisable } from './chart/VSync.js'; -import { binderStruct } from '../database/ui-worker/procedureWorkerBinder.js'; function dpr() { return window.devicePixelRatio || 1; @@ -265,8 +263,6 @@ export class SpSystemTrace extends BaseElement { } startPoint.y = startPoint.rowEL!.translateY! + startPoint.offsetY; endPoint.y = endPoint.rowEL!.translateY! + endPoint.offsetY; - startPoint.backrowEL = startPoint.rowEL; - endPoint.backrowEL = endPoint.rowEL; this.linkNodes.push([startPoint, endPoint]); } @@ -785,8 +781,8 @@ export class SpSystemTrace extends BaseElement { let isIntersect = (filterFunc: FuncStruct, rangeData: RangeSelectStruct) => Math.max(filterFunc.startTs! + filterFunc.dur!, rangeData!.endNS || 0) - - Math.min(filterFunc.startTs!, rangeData!.startNS || 0) < - filterFunc.dur! + (rangeData!.endNS || 0) - (rangeData!.startNS || 0) && + Math.min(filterFunc.startTs!, rangeData!.startNS || 0) < + filterFunc.dur! + (rangeData!.endNS || 0) - (rangeData!.startNS || 0) && filterFunc.funName!.indexOf('H:Task ') >= 0; let taskData = it.dataList.filter((taskData: FuncStruct) => { taskData!.tid = parseInt(it.rowId!); @@ -1171,7 +1167,7 @@ export class SpSystemTrace extends BaseElement { } else if (it.rowType == TraceRow.ROW_TYPE_JANK) { let isIntersect = (filterJank: JanksStruct, rangeData: RangeSelectStruct) => Math.max(filterJank.ts! + filterJank.dur!, rangeData!.endNS || 0) - - Math.min(filterJank.ts!, rangeData!.startNS || 0) < + Math.min(filterJank.ts!, rangeData!.startNS || 0) < filterJank.dur! + (rangeData!.endNS || 0) - (rangeData!.startNS || 0); if (it.name == 'Actual Timeline') { selection.jankFramesData = []; @@ -1254,7 +1250,7 @@ export class SpSystemTrace extends BaseElement { } else if (it.rowType == TraceRow.ROW_TYPE_FRAME_ANIMATION) { let isIntersect = (animationStruct: FrameAnimationStruct, selectStruct: RangeSelectStruct) => Math.max(animationStruct.startTs! + animationStruct.dur!, selectStruct!.endNS || 0) - - Math.min(animationStruct.startTs!, selectStruct!.startNS || 0) < + Math.min(animationStruct.startTs!, selectStruct!.startNS || 0) < animationStruct.dur! + (selectStruct!.endNS || 0) - (selectStruct!.startNS || 0); let frameAnimationList = it.dataList.filter((frameAnimationBean: FrameAnimationStruct) => { return isIntersect(frameAnimationBean, TraceRow.rangeSelectObject!); @@ -1434,7 +1430,7 @@ export class SpSystemTrace extends BaseElement { window.subscribe(window.SmartEvent.UI.SliceMark, (data) => { this.sliceMarkEventHandler(data); }); - window.subscribe(window.SmartEvent.UI.TraceRowComplete, (tr) => { }); + window.subscribe(window.SmartEvent.UI.TraceRowComplete, (tr) => {}); window.subscribe(window.SmartEvent.UI.RefreshCanvas, () => { this.refreshCanvas(false); }); @@ -1896,7 +1892,7 @@ export class SpSystemTrace extends BaseElement { // 如果没有找到帽子,则绘制一个旗子 let time = Math.round( (x * (TraceRow.range?.endNS! - TraceRow.range?.startNS!)) / this.timerShaftEL!.canvas!.offsetWidth + - TraceRow.range?.startNS! + TraceRow.range?.startNS! ); this.timerShaftEL!.sportRuler!.drawTriangle(time, 'squre'); } @@ -2081,13 +2077,13 @@ export class SpSystemTrace extends BaseElement { this.timerShaftEL?.setSlicesMark( FrameAnimationStruct.selectFrameAnimationStruct.startTs || 0, (FrameAnimationStruct.selectFrameAnimationStruct.startTs || 0) + - (FrameAnimationStruct.selectFrameAnimationStruct.dur || 0) + (FrameAnimationStruct.selectFrameAnimationStruct.dur || 0) ); } else if (JsCpuProfilerStruct.selectJsCpuProfilerStruct) { this.timerShaftEL?.setSlicesMark( JsCpuProfilerStruct.selectJsCpuProfilerStruct.startTime || 0, (JsCpuProfilerStruct.selectJsCpuProfilerStruct.startTime || 0) + - (JsCpuProfilerStruct.selectJsCpuProfilerStruct.totalTime || 0) + (JsCpuProfilerStruct.selectJsCpuProfilerStruct.totalTime || 0) ); } else { this.slicestime = this.timerShaftEL?.setSlicesMark(); @@ -2539,7 +2535,7 @@ export class SpSystemTrace extends BaseElement { if (!SportRuler.isMouseInSportRuler) { this.traceSheetEL?.setAttribute('mode', 'hidden'); } - this.removeLinkLinesByBusinessType('task', 'thread'); + this.removeLinkLinesByBusinessType('task'); this.refreshCanvas(true); JankStruct.delJankLineFlag = true; } @@ -2575,10 +2571,6 @@ export class SpSystemTrace extends BaseElement { TraceRow.ROW_TYPE_APP_STARTUP, () => AppStartupStruct.hoverStartupStruct !== null && AppStartupStruct.hoverStartupStruct !== undefined, ], - [ - TraceRow.ROW_TYPE_ALL_APPSTARTUPS, - () => AllAppStartupStruct.hoverStartupStruct !== null && AllAppStartupStruct.hoverStartupStruct !== undefined, - ], [TraceRow.ROW_TYPE_STATIC_INIT, () => SoStruct.hoverSoStruct !== null && SoStruct.hoverSoStruct !== undefined], [TraceRow.ROW_TYPE_JANK, () => JankStruct.hoverJankStruct !== null && JankStruct.hoverJankStruct !== undefined], [TraceRow.ROW_TYPE_HEAP, () => HeapStruct.hoverHeapStruct !== null && HeapStruct.hoverHeapStruct !== undefined], @@ -2744,7 +2736,6 @@ export class SpSystemTrace extends BaseElement { this.traceSheetEL?.displayCpuData( CpuStruct.selectCpuStruct!, (wakeUpBean) => { - this.removeLinkLinesByBusinessType('thread'); CpuStruct.wakeupBean = wakeUpBean; this.refreshCanvas(true); }, @@ -2833,7 +2824,6 @@ export class SpSystemTrace extends BaseElement { ); } this.hoverStructNull(); - let flag = JSON.parse(JSON.stringify(ThreadStruct.selectThreadStruct)); this.selectStructNull(); this.wakeupListNull(); ThreadStruct.hoverThreadStruct = findEntry; @@ -2844,16 +2834,7 @@ export class SpSystemTrace extends BaseElement { threadClickHandler, cpuClickHandler, threadClickPreviousHandler, - threadClickNextHandler, - (datas) => { - this.removeLinkLinesByBusinessType('thread'); - datas.forEach((data) => { - let endParentRow = this.shadowRoot?.querySelector>( - `trace-row[row-id='${data.pid}'][folder]` - ); - this.drawThreadLine(endParentRow, flag, data); - }); - } + threadClickNextHandler ); this.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true); } @@ -2970,7 +2951,6 @@ export class SpSystemTrace extends BaseElement { ); this.timerShaftEL?.modifyFlagList(undefined); } else if (clickRowType === TraceRow.ROW_TYPE_THREAD && ThreadStruct.hoverThreadStruct) { - this.removeLinkLinesByBusinessType('thread'); ThreadStruct.selectThreadStruct = ThreadStruct.hoverThreadStruct; this.timerShaftEL?.drawTriangle(ThreadStruct.selectThreadStruct!.startTime || 0, 'inverted'); this.traceSheetEL?.displayThreadData( @@ -3154,10 +3134,6 @@ export class SpSystemTrace extends BaseElement { AppStartupStruct.selectStartupStruct = AppStartupStruct.hoverStartupStruct; this.traceSheetEL?.displayStartupData(AppStartupStruct.selectStartupStruct, scrollToFuncHandler); this.timerShaftEL?.modifyFlagList(undefined); - } else if (clickRowType === TraceRow.ROW_TYPE_ALL_APPSTARTUPS && AllAppStartupStruct.hoverStartupStruct) { - AllAppStartupStruct.selectStartupStruct = AllAppStartupStruct.hoverStartupStruct; - this.traceSheetEL?.displayAllStartupData(AllAppStartupStruct.selectStartupStruct!, scrollToFuncHandler) - this.timerShaftEL?.modifyFlagList(undefined); } else if (clickRowType === TraceRow.ROW_TYPE_STATIC_INIT && SoStruct.hoverSoStruct) { SoStruct.selectSoStruct = SoStruct.hoverSoStruct; this.traceSheetEL?.displayStaticInitData(SoStruct.selectSoStruct, scrollToFuncHandler); @@ -3250,9 +3226,6 @@ export class SpSystemTrace extends BaseElement { if (!JankStruct.selectJankStruct) { this.removeLinkLinesByBusinessType('janks'); } - if (!ThreadStruct.selectThreadStruct) { - this.removeLinkLinesByBusinessType('thread'); - } if (row) { let pointEvent = this.createPointEvent(row); SpStatisticsHttpUtil.addOrdinaryVisitAction({ @@ -3696,110 +3669,6 @@ export class SpSystemTrace extends BaseElement { } } - drawThreadLine(endParentRow: any, selectThreadStruct: ThreadStruct, data: any) { - let collectList = this.favoriteChartListEL!.getCollectRows(); - let startRow: any; - if (selectThreadStruct == undefined || selectThreadStruct == null) { - return; - } - let selectRowId = selectThreadStruct?.tid; - startRow = this.shadowRoot?.querySelector>( - `trace-row[row-id='${selectRowId}'][row-type='thread']` - ); - if (!startRow) { - for (let index = 0; index < collectList.length; index++) { - let collectChart = collectList[index]; - if (collectChart.rowId === selectRowId?.toString() && collectChart.rowType === 'thread') { - startRow = collectChart; - break; - } - } - } - function collectionHasThread(threadRow: any): boolean { - for (let item of collectList!) { - if (item.rowId === threadRow.rowId && item.rowType === threadRow.rowType) { - return false; - } - } - return true; - } - - if (endParentRow) { - //终点的父泳道过滤出选中的Struct - let endRowStruct: any; - //泳道展开的情况,查找endRowStruct - endRowStruct = this.shadowRoot?.querySelector>( - `trace-row[row-id='${data.tid}'][row-type='thread']` - ); - //泳道未展开的情况,查找endRowStruct - if (!endRowStruct) { - endRowStruct = endParentRow.childrenList.find((item: TraceRow) => { - return item.rowId === `${data.tid}` && item.rowType === 'thread' - }); - } - if (endRowStruct) { - let findJankEntry = endRowStruct!.dataList!.find((dat: any) => dat.startTime == data.startTime && dat.dur! > 0); - //连线规则 - let ts: number = 0; - if (findJankEntry) { - ts = selectThreadStruct.startTime! + selectThreadStruct.dur! / 2; - let startParentRow: any; - // startRow为子泳道,子泳道不存在,使用父泳道 - if (startRow) { - startParentRow = this.shadowRoot?.querySelector>( - `trace-row[row-id='${startRow.rowParentId}'][folder]` - ); - } else { - startRow = this.shadowRoot?.querySelector>( - `trace-row[row-id='${selectThreadStruct?.pid}'][folder]` - ); - } - let endY = endRowStruct!.translateY!; - let endRowEl = endRowStruct; - let endOffSetY = 20 * 0.5; - let expansionFlag = collectionHasThread(endRowStruct); - if (!endParentRow.expansion && expansionFlag) { - endY = endParentRow!.translateY!; - endRowEl = endParentRow; - endOffSetY = 10 * 0.5; - } - let startY = startRow!.translateY!; - let startRowEl = startRow; - let startOffSetY = 20 * 0.5; - expansionFlag = collectionHasThread(startRow); - if (startParentRow && !startParentRow.expansion && expansionFlag) { - startY = startParentRow!.translateY!; - startRowEl = startParentRow; - startOffSetY = 10 * 0.5; - } - this.addPointPair( - this.makePoint( - ns2xByTimeShaft(ts, this.timerShaftEL!), - ts, - startY, - startRowEl!, - startOffSetY, - 'thread', - LineType.StraightLine, - selectThreadStruct.startTime == ts, - ), - this.makePoint( - ns2xByTimeShaft(findJankEntry.startTime!, this.timerShaftEL!), - findJankEntry.startTime!, - endY, - endRowEl, - endOffSetY, - 'thread', - LineType.StraightLine, - true, - ) - ); - this.refreshCanvas(true); - } - } - } - } - translateByMouseMove(ev: MouseEvent): void { ev.preventDefault(); let offset = 0; @@ -4536,8 +4405,8 @@ export class SpSystemTrace extends BaseElement { procedurePool.clearCache(); Utils.clearData(); InitAnalysis.getInstance().isInitAnalysis = true; - procedurePool.submitWithName('logic0', 'clear', {}, undefined, (res: any) => { }); - procedurePool.submitWithName('logic1', 'clear', {}, undefined, (res: any) => { }); + procedurePool.submitWithName('logic0', 'clear', {}, undefined, (res: any) => {}); + procedurePool.submitWithName('logic1', 'clear', {}, undefined, (res: any) => {}); this.times.clear(); setVSyncDisable(); } @@ -4696,15 +4565,12 @@ export class SpSystemTrace extends BaseElement { } if (this.tipEL) { this.tipEL.innerHTML = html; - if (row.rowType === TraceRow.ROW_TYPE_JS_CPU_PROFILER || row.rowType === TraceRow.ROW_TYPE_PERF_CALLCHART || row.rowType === TraceRow.ROW_TYPE_BINDER_COUNT) { + if (row.rowType === TraceRow.ROW_TYPE_JS_CPU_PROFILER || row.rowType === TraceRow.ROW_TYPE_PERF_CALLCHART) { this.tipEL.style.maxWidth = row.clientWidth / 3 + 'px'; this.tipEL.style.wordBreak = ' break-all'; this.tipEL.style.height = 'unset'; this.tipEL.style.display = 'block'; y = y + struct.depth * 20; - if (row.rowType === TraceRow.ROW_TYPE_BINDER_COUNT) { - y = row.hoverY + row.getBoundingClientRect().top - this.getBoundingClientRect().top; - } } else { this.tipEL.style.display = 'flex'; this.tipEL.style.height = row.style.height; diff --git a/ide/src/trace/component/chart/SpAllAppStartups.ts b/ide/src/trace/component/chart/SpAllAppStartups.ts deleted file mode 100644 index d12ed4015..000000000 --- a/ide/src/trace/component/chart/SpAllAppStartups.ts +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { CpuFreqStruct } from '../../database/ui-worker/ProcedureWorkerFreq.js'; -import { - queryAppStartupProcessIds, - queryProcessStartup, - querySingleAppStartupsName, -} from '../../database/SqlLite.js'; -import { FlagsConfig } from '../SpFlags.js'; -import { AllAppStartupStruct, AllAppStartupRender } from '../../database/ui-worker/ProcedureWorkerAllAppStartup.js'; - -export class SpAllAppStartupsChart { - private readonly trace: SpSystemTrace | undefined; - static APP_STARTUP_PID_ARR: Array = []; - static jsonRow: TraceRow | undefined; - static trace: SpSystemTrace; - static AllAppStartupsNameArr: any[] = []; - static allAppStartupsAva: number[] = []; - - constructor(trace: SpSystemTrace) { - SpAllAppStartupsChart.trace = trace; - } - - - - - - async init() { - SpAllAppStartupsChart.APP_STARTUP_PID_ARR = []; - let appStartUpPids = await queryAppStartupProcessIds(); - appStartUpPids.forEach((it) => SpAllAppStartupsChart.APP_STARTUP_PID_ARR.push(it.pid)); - SpAllAppStartupsChart.AllAppStartupsNameArr = []; - SpAllAppStartupsChart.allAppStartupsAva = []; - for (let i = 0; i < SpAllAppStartupsChart.APP_STARTUP_PID_ARR.length; i++) { - let tmpSingleApp: any[] = await queryProcessStartup(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]!); - if (tmpSingleApp.length == 8) { - let avilSingleName = await querySingleAppStartupsName(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]!); - SpAllAppStartupsChart.allAppStartupsAva.push(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]); - SpAllAppStartupsChart.AllAppStartupsNameArr.push(avilSingleName![0].name); - } - } - let loadAppStartup: boolean = FlagsConfig.getFlagsConfigEnableStatus('AppStartup'); - if (loadAppStartup && SpAllAppStartupsChart.allAppStartupsAva.length) await this.initFolder(); - } - - async initFolder() { - let row: TraceRow = TraceRow.skeleton(); - row.setAttribute('hasStartup', 'true'); - row.rowId = `all-app-start-${SpAllAppStartupsChart.APP_STARTUP_PID_ARR![0]}`; - row.index = 0; - row.rowType = TraceRow.ROW_TYPE_ALL_APPSTARTUPS; - row.rowParentId = ''; - row.folder = false; - row.style.height = '40px'; - row.name = `All App Startups`; - row.selectChangeHandler = SpAllAppStartupsChart.trace.selectChangeHandler; - row.favoriteChangeHandler = SpAllAppStartupsChart.trace.favoriteChangeHandler; - row.supplier = async (): Promise> => { - let sendRes: AllAppStartupStruct[] | PromiseLike = []; - for (let i = 0; i < SpAllAppStartupsChart.allAppStartupsAva.length; i++) { - let tmpResArr = await queryProcessStartup(SpAllAppStartupsChart.allAppStartupsAva[i]); - let maxStartTs: number | undefined = tmpResArr[0].startTs; - let minStartTs: number | undefined = tmpResArr[0].startTs; - let singleDur = tmpResArr[0].dur; - let endTs: number | undefined = tmpResArr[0].startTs; - if (tmpResArr.length > 1) { - for (let j = 0; j < tmpResArr.length; j++) { - if (Number(tmpResArr[j].startTs) > Number(maxStartTs)) { - maxStartTs = tmpResArr[j].startTs; - } else if (Number(tmpResArr[j].startTs) < Number(minStartTs)) { - minStartTs = tmpResArr[j].startTs; - } - } - tmpResArr.forEach((item) => { - if (item.startTs == maxStartTs) { - endTs = Number(item.startTs) + Number(item.dur); - singleDur = Number(endTs) - Number(minStartTs); - } - }) - } else if (tmpResArr.length === 1) { - minStartTs = tmpResArr[0].startTs; - singleDur = tmpResArr[0].dur; - } - sendRes.push( - { - dur: singleDur, - value: undefined, - startTs: minStartTs, - pid: SpAllAppStartupsChart.allAppStartupsAva[i], - process: undefined, - itid: undefined, - endItid: undefined, - tid: SpAllAppStartupsChart.allAppStartupsAva[i], - startName: undefined, - stepName: SpAllAppStartupsChart.AllAppStartupsNameArr[i], - translateY: undefined, - frame: undefined, - isHover: false - } - ) - } - return sendRes - } - - row.onThreadHandler = (useCache): void => { - let context: CanvasRenderingContext2D; - if (row.currentContext) { - context = row.currentContext; - } else { - context = row.collect ? SpAllAppStartupsChart.trace.canvasFavoritePanelCtx! : SpAllAppStartupsChart.trace.canvasPanelCtx!; - } - row.canvasSave(context); - (renders['all-app-start-up'] as AllAppStartupRender).renderMainThread( - { - appStartupContext: context, - useCache: useCache, - type: `app-startup ${row.rowId}`, - }, - row - ); - row.canvasRestore(context); - }; - SpAllAppStartupsChart.trace.rowsEL?.appendChild(row); - } -} diff --git a/ide/src/trace/component/chart/SpChartManager.ts b/ide/src/trace/component/chart/SpChartManager.ts index ce26806d6..a8fa7c6f7 100644 --- a/ide/src/trace/component/chart/SpChartManager.ts +++ b/ide/src/trace/component/chart/SpChartManager.ts @@ -49,9 +49,7 @@ import { MemoryConfig } from '../../bean/MemoryConfig.js'; import { FlagsConfig } from '../SpFlags.js'; import { SpLogChart } from './SpLogChart.js'; import { SpHiSysEventChart } from './SpHiSysEventChart.js'; -import { SpAllAppStartupsChart } from './SpAllAppStartups.js'; import {setVSyncData} from './VSync.js'; -import { SegMenTaTion } from './SpSegmentationChart.js'; export class SpChartManager { static APP_STARTUP_PID_ARR: Array = []; @@ -71,12 +69,10 @@ export class SpChartManager { private smapsChart: VmTrackerChart; private clockChart: SpClockChart; private irqChart: SpIrqChart; - private SpAllAppStartupsChart!: SpAllAppStartupsChart; frameTimeChart: SpFrameTimeChart; public arkTsChart: SpArkTsChart; private logChart: SpLogChart; private spHiSysEvent: SpHiSysEventChart; - private SegMenTaTion:SegMenTaTion; constructor(trace: SpSystemTrace) { this.trace = trace; @@ -98,8 +94,6 @@ export class SpChartManager { this.arkTsChart = new SpArkTsChart(trace); this.logChart = new SpLogChart(trace); this.spHiSysEvent = new SpHiSysEventChart(trace); - this.SpAllAppStartupsChart = new SpAllAppStartupsChart(trace); - this.SegMenTaTion = new SegMenTaTion(trace); } async init(progress: Function) { @@ -143,7 +137,6 @@ export class SpChartManager { await this.clockChart.init(); progress('Irq init', 84); await this.irqChart.init(); - await this.SegMenTaTion.init(); info('Cpu Freq Data initialized'); await this.virtualMemChart.init(); progress('fps', 85); @@ -171,7 +164,6 @@ export class SpChartManager { progress('ark ts', 90); await this.arkTsChart.initFolder(); info('ark ts initialized'); - await this.SpAllAppStartupsChart.init(); await this.frameTimeChart.init(); progress('process', 92); await this.process.initAsyncFuncData(); diff --git a/ide/src/trace/component/chart/SpProcessChart.ts b/ide/src/trace/component/chart/SpProcessChart.ts index 56cc3717c..d4e2d0684 100644 --- a/ide/src/trace/component/chart/SpProcessChart.ts +++ b/ide/src/trace/component/chart/SpProcessChart.ts @@ -431,146 +431,75 @@ export class SpProcessChart { if (offsetYTimeOut) { clearTimeout(offsetYTimeOut); } - if (JankStruct.selectJankStruct !== null && JankStruct.selectJankStruct !== undefined) { - if (e.detail.expansion) { - offsetYTimeOut = setTimeout(() => { - this.trace.linkNodes.forEach((linkNodeItem) => { - JankStruct.selectJankStructList?.forEach((selectProcessStruct: any) => { - if (e.detail.rowId == selectProcessStruct.pid) { - JankStruct.selectJankStruct = selectProcessStruct; - JankStruct.hoverJankStruct = selectProcessStruct; - } - }); - if (linkNodeItem[0].rowEL.collect) { - linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.getBoundingClientRect().top - 195; - } else { - linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } - linkNodeItem[0].y = linkNodeItem[0].rowEL!.translateY! + linkNodeItem[0].offsetY; - if (linkNodeItem[1].rowEL.collect) { - linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.getBoundingClientRect().top - 195; - } else { - linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } - linkNodeItem[1].y = linkNodeItem[1].rowEL!.translateY! + linkNodeItem[1].offsetY; - if (actualRow) { - if (linkNodeItem[0].rowEL.rowId == e.detail.rowId) { - linkNodeItem[0].x = ns2xByTimeShaft(linkNodeItem[0].ns, this.trace.timerShaftEL!); - linkNodeItem[0].y = actualRow!.translateY! + linkNodeItem[0].offsetY * 2; - linkNodeItem[0].offsetY = linkNodeItem[0].offsetY * 2; - linkNodeItem[0].rowEL = actualRow!; - } else if (linkNodeItem[1].rowEL.rowId == e.detail.rowId) { - linkNodeItem[1].x = ns2xByTimeShaft(linkNodeItem[1].ns, this.trace.timerShaftEL!); - linkNodeItem[1].y = actualRow!.translateY! + linkNodeItem[1].offsetY * 2; - linkNodeItem[1].offsetY = linkNodeItem[1].offsetY * 2; - linkNodeItem[1].rowEL = actualRow!; - } - } - }); - }, 300); - } else { - if (JankStruct!.selectJankStruct) { - JankStruct.selectJankStructList?.push(JankStruct!.selectJankStruct); - } - offsetYTimeOut = setTimeout(() => { - this.trace.linkNodes?.forEach((linkProcessItem) => { - if (linkProcessItem[0].rowEL.collect) { - linkProcessItem[0].rowEL.translateY = linkProcessItem[0].rowEL.getBoundingClientRect().top - 195; - } else { - linkProcessItem[0].rowEL.translateY = - linkProcessItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } - linkProcessItem[0].y = linkProcessItem[0].rowEL!.translateY! + linkProcessItem[0].offsetY; - if (linkProcessItem[1].rowEL.collect) { - linkProcessItem[1].rowEL.translateY = linkProcessItem[1].rowEL.getBoundingClientRect().top - 195; - } else { - linkProcessItem[1].rowEL.translateY = - linkProcessItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } - linkProcessItem[1].y = linkProcessItem[1].rowEL!.translateY! + linkProcessItem[1].offsetY; - if (linkProcessItem[0].rowEL.rowParentId == e.detail.rowId) { - linkProcessItem[0].x = ns2xByTimeShaft(linkProcessItem[0].ns, this.trace.timerShaftEL!); - linkProcessItem[0].y = processRow!.translateY! + linkProcessItem[0].offsetY / 2; - linkProcessItem[0].offsetY = linkProcessItem[0].offsetY / 2; - linkProcessItem[0].rowEL = processRow!; - } else if (linkProcessItem[1].rowEL.rowParentId == e.detail.rowId) { - linkProcessItem[1].x = ns2xByTimeShaft(linkProcessItem[1].ns, this.trace.timerShaftEL!); - linkProcessItem[1].y = processRow!.translateY! + linkProcessItem[1].offsetY / 2; - linkProcessItem[1].offsetY = linkProcessItem[1].offsetY / 2; - linkProcessItem[1].rowEL = processRow!; + if (e.detail.expansion) { + offsetYTimeOut = setTimeout(() => { + this.trace.linkNodes.forEach((linkNodeItem) => { + JankStruct.selectJankStructList?.forEach((selectProcessStruct: any) => { + if (e.detail.rowId == selectProcessStruct.pid) { + JankStruct.selectJankStruct = selectProcessStruct; + JankStruct.hoverJankStruct = selectProcessStruct; } }); - }, 300); - } - } else { - if (e.detail.expansion) { - offsetYTimeOut = setTimeout(() => { - this.trace.linkNodes.forEach((linkNodeItem) => { - ThreadStruct.selectThreadStructList?.forEach((selectProcessStruct: any) => { - if (e.detail.rowId == selectProcessStruct.pid) { - ThreadStruct.selectThreadStruct = selectProcessStruct; - ThreadStruct.hoverThreadStruct = selectProcessStruct; - } - }); - if (linkNodeItem[0].rowEL.expansion && linkNodeItem[0].backrowEL) { - linkNodeItem[0].rowEL = linkNodeItem[0].backrowEL; - if (linkNodeItem[0].rowEL.collect) { - linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.getBoundingClientRect().top - 195; - } else { - linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } + if (linkNodeItem[0].rowEL.collect) { + linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.getBoundingClientRect().top - 195; + } else { + linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } + linkNodeItem[0].y = linkNodeItem[0].rowEL!.translateY! + linkNodeItem[0].offsetY; + if (linkNodeItem[1].rowEL.collect) { + linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.getBoundingClientRect().top - 195; + } else { + linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } + linkNodeItem[1].y = linkNodeItem[1].rowEL!.translateY! + linkNodeItem[1].offsetY; + if (actualRow) { + if (linkNodeItem[0].rowEL.rowId == e.detail.rowId) { linkNodeItem[0].x = ns2xByTimeShaft(linkNodeItem[0].ns, this.trace.timerShaftEL!); + linkNodeItem[0].y = actualRow!.translateY! + linkNodeItem[0].offsetY * 2; linkNodeItem[0].offsetY = linkNodeItem[0].offsetY * 2; - linkNodeItem[0].y = linkNodeItem[0].rowEL.translateY + linkNodeItem[0].offsetY; - } - if (linkNodeItem[1].rowEL.expansion && linkNodeItem[1].backrowEL) { - linkNodeItem[1].rowEL = linkNodeItem[1].backrowEL; - if (linkNodeItem[1].rowEL.collect) { - linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.getBoundingClientRect().top - 195; - } else { - linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } + linkNodeItem[0].rowEL = actualRow!; + } else if (linkNodeItem[1].rowEL.rowId == e.detail.rowId) { linkNodeItem[1].x = ns2xByTimeShaft(linkNodeItem[1].ns, this.trace.timerShaftEL!); + linkNodeItem[1].y = actualRow!.translateY! + linkNodeItem[1].offsetY * 2; linkNodeItem[1].offsetY = linkNodeItem[1].offsetY * 2; - linkNodeItem[1].y = linkNodeItem[1].rowEL!.translateY! + linkNodeItem[1].offsetY; - } - }); - }, 300); - } else { - if (ThreadStruct!.selectThreadStruct) { - ThreadStruct.selectThreadStructList?.push(ThreadStruct!.selectThreadStruct); - } - offsetYTimeOut = setTimeout(() => { - this.trace.linkNodes?.forEach((linkProcessItem) => { - if (linkProcessItem[0].rowEL.collect) { - linkProcessItem[0].rowEL.translateY = linkProcessItem[0].rowEL.getBoundingClientRect().top - 195; - } else { - linkProcessItem[0].rowEL.translateY = - linkProcessItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } - linkProcessItem[0].y = processRow!.translateY + linkProcessItem[0].offsetY;//11 - if (linkProcessItem[1].rowEL.collect) { - linkProcessItem[1].rowEL.translateY = linkProcessItem[1].rowEL.getBoundingClientRect().top - 195; - } else { - linkProcessItem[1].rowEL.translateY = - linkProcessItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } - linkProcessItem[1].y = linkProcessItem[1].rowEL!.translateY + linkProcessItem[1].offsetY; - if (linkProcessItem[0].rowEL.rowParentId == e.detail.rowId) { - linkProcessItem[0].x = ns2xByTimeShaft(linkProcessItem[0].ns, this.trace.timerShaftEL!); - linkProcessItem[0].y = processRow!.translateY! + linkProcessItem[0].offsetY / 2; - linkProcessItem[0].offsetY = linkProcessItem[0].offsetY / 2; - linkProcessItem[0].rowEL = processRow!; + linkNodeItem[1].rowEL = actualRow!; } - if (linkProcessItem[1].rowEL.rowParentId == e.detail.rowId) { - linkProcessItem[1].x = ns2xByTimeShaft(linkProcessItem[1].ns, this.trace.timerShaftEL!); - linkProcessItem[1].y = processRow!.translateY! + linkProcessItem[1].offsetY / 2; - linkProcessItem[1].offsetY = linkProcessItem[1].offsetY / 2; - linkProcessItem[1].rowEL = processRow!; - } - }); - }, 300); + } + }); + }, 300); + } else { + if (JankStruct!.selectJankStruct) { + JankStruct.selectJankStructList?.push(JankStruct!.selectJankStruct); } + offsetYTimeOut = setTimeout(() => { + this.trace.linkNodes?.forEach((linkProcessItem) => { + if (linkProcessItem[0].rowEL.collect) { + linkProcessItem[0].rowEL.translateY = linkProcessItem[0].rowEL.getBoundingClientRect().top - 195; + } else { + linkProcessItem[0].rowEL.translateY = + linkProcessItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } + linkProcessItem[0].y = linkProcessItem[0].rowEL!.translateY! + linkProcessItem[0].offsetY; + if (linkProcessItem[1].rowEL.collect) { + linkProcessItem[1].rowEL.translateY = linkProcessItem[1].rowEL.getBoundingClientRect().top - 195; + } else { + linkProcessItem[1].rowEL.translateY = + linkProcessItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } + linkProcessItem[1].y = linkProcessItem[1].rowEL!.translateY! + linkProcessItem[1].offsetY; + if (linkProcessItem[0].rowEL.rowParentId == e.detail.rowId) { + linkProcessItem[0].x = ns2xByTimeShaft(linkProcessItem[0].ns, this.trace.timerShaftEL!); + linkProcessItem[0].y = processRow!.translateY! + linkProcessItem[0].offsetY / 2; + linkProcessItem[0].offsetY = linkProcessItem[0].offsetY / 2; + linkProcessItem[0].rowEL = processRow!; + } else if (linkProcessItem[1].rowEL.rowParentId == e.detail.rowId) { + linkProcessItem[1].x = ns2xByTimeShaft(linkProcessItem[1].ns, this.trace.timerShaftEL!); + linkProcessItem[1].y = processRow!.translateY! + linkProcessItem[1].offsetY / 2; + linkProcessItem[1].offsetY = linkProcessItem[1].offsetY / 2; + linkProcessItem[1].rowEL = processRow!; + } + }); + }, 300); } let refreshTimeOut = setTimeout(() => { this.trace.refreshCanvas(true); diff --git a/ide/src/trace/component/chart/SpSegmentationChart.ts b/ide/src/trace/component/chart/SpSegmentationChart.ts deleted file mode 100644 index 443ef90ac..000000000 --- a/ide/src/trace/component/chart/SpSegmentationChart.ts +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { ColorUtils } from '../trace/base/ColorUtils.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { info } from '../../../log/Log.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { FreqExtendRender, CpuFreqExtendStruct } from '../../database/ui-worker/ProcedureWorkerFreqExtend.js'; -import { BinderRender, binderStruct } from '../../database/ui-worker/procedureWorkerBinder.js'; -import { queryIrqList } from '../../database/SqlLite.js'; - -export class SegMenTaTion { - static trace: SpSystemTrace; - static jsonRow: TraceRow | undefined; - static GpuRow: TraceRow | undefined; - static binderRow: TraceRow | undefined; - static schedRow: TraceRow | undefined; - static freqInfoMapData: any = new Map(); - private rowFolder!: TraceRow; - static chartData: any; - // 数据切割联动 - static setChartData(type: string, data: any) { - this.tabHover(type, false) - let currentMaxValue = 0; - if (type === 'CPU-FREQ') { - let chartData = data.map((v: any) => { - if (v.value > currentMaxValue) { - currentMaxValue = v.value - } - return { - cpu: 0, - dur: v.dur, - value: v.value, - startNS: v.startNS, - cycle: v.cycle, - freq: v.freq - } - }) - CpuFreqExtendStruct.maxValue = currentMaxValue; - SegMenTaTion.jsonRow!.dataList = []; - SegMenTaTion.jsonRow!.dataListCache = []; - SegMenTaTion.jsonRow!.isComplete = false; - SegMenTaTion.jsonRow!.supplier = (): Promise> => - new Promise>((resolve) => resolve(chartData)); - } - else if (type === 'GPU-FREQ') { - let chartData = data.map((v: any) => { - let _count = Number(v.count) - if (_count > currentMaxValue) { - currentMaxValue = _count - } - return { - cpu: 7, - dur: Number(v.dur * 1000000), - value: _count, - startNS: v.startNS, - cycle: v.cycle, - type - } - }) - CpuFreqExtendStruct.maxValue = currentMaxValue; - SegMenTaTion.GpuRow!.dataList = []; - SegMenTaTion.GpuRow!.dataListCache = []; - SegMenTaTion.GpuRow!.isComplete = false; - SegMenTaTion.GpuRow!.supplier = (): Promise> => - new Promise>((resolve) => resolve(chartData)); - SegMenTaTion.trace.refreshCanvas(true) - } else if (type === 'SCHED-SWITCH') { - let chartData = data.map((v: any) => { - if (v.count > currentMaxValue) { - currentMaxValue = v.count - } - return { - cpu: 5, - dur: Number(v.duration) * 1000 * 1000, - value: v.count, - startNS: Number(v.cycleStartTime) * 1000 * 1000, - cycle: v.cycle, - type - } - }) - CpuFreqExtendStruct.maxValue = currentMaxValue; - SegMenTaTion.schedRow!.dataList = []; - SegMenTaTion.schedRow!.dataListCache = []; - SegMenTaTion.schedRow!.isComplete = false; - SegMenTaTion.schedRow!.supplier = (): Promise> => - new Promise>((resolve) => resolve(chartData)); - } else if (type === 'BINDER') { - binderStruct.maxHeight = 0; - let binderList: any = []; - let chartData: any; - data.map((v: any) => { - let listCount = 0; - v.map((t: any) => { - listCount += t.count - if (t.name === 'binder transaction') { - t.depth = t.count - } - if (t.name === 'binder transaction async') { - t.depth = t.count + ((v.filter((i: any) => { - return i.name === 'binder transaction' - }).length > 0) ? (v.filter((i: any) => { - return i.name === 'binder transaction' - })[0].count) : 0); - } - if (t.name === 'binder reply') { - t.depth = t.count + ((v.filter((i: any) => { - return i.name === 'binder transaction' - }).length > 0) ? (v.filter((i: any) => { - return i.name === 'binder transaction' - })[0].count) : 0) + ((v.filter((i: any) => { - return i.name === 'binder transaction async' - }).length > 0) ? (v.filter((i: any) => { - return i.name === 'binder transaction async' - })[0].count) : 0); - } - if (t.name === 'binder async rcv') { - t.depth = t.count + ((v.filter((i: any) => { - return i.name === 'binder transaction' - }).length > 0) ? (v.filter((i: any) => { - return i.name === 'binder transaction' - })[0].count) : 0) + ((v.filter((i: any) => { - return i.name === 'binder transaction async' - }).length > 0) ? (v.filter((i: any) => { - return i.name === 'binder transaction async' - })[0].count) : 0) + ((v.filter((i: any) => { - return i.name === 'binder reply' - }).length > 0) ? (v.filter((i: any) => { - return i.name === 'binder reply' - })[0].count) : 0) - } - binderList.push(t); - }); - binderStruct.maxHeight = binderStruct.maxHeight > listCount ? binderStruct.maxHeight : JSON.parse(JSON.stringify(listCount)); - listCount = 0 - }) - chartData = binderList.map((v: any) => { - return { - cpu: v.name === 'binder transaction' ? - 0 : v.name === 'binder transaction async' ? - 1 : v.name === 'binder reply' ? - 2 : 3, - startNS: v.startNS, - dur: v.dur, - name: `${v.name}`, - value: v.count, - depth: v.depth, - cycle: v.idx, - } - }) - SegMenTaTion.binderRow!.dataList = []; - SegMenTaTion.binderRow!.dataListCache = []; - SegMenTaTion.binderRow!.isComplete = false; - SegMenTaTion.binderRow!.style.height = `${binderStruct.maxHeight > 2 ? binderStruct.maxHeight * 20 + 20 : 40}px`; - SegMenTaTion.binderRow!.supplier = (): Promise> => - new Promise>((resolve) => resolve(chartData)); - } else { - return - } - SegMenTaTion.trace.refreshCanvas(true) - } - - // 悬浮联动 - static tabHover(type: String, tableIsHover: any = false, cycle: number = -1) { - CpuFreqExtendStruct.isTabHover = tableIsHover; - if (type === 'CPU-FREQ' || type === 'GPU-FREQ' || type === 'SCHED-SWITCH') { - if (tableIsHover) { - SegMenTaTion.GpuRow!.isHover = false; - CpuFreqExtendStruct.cycle = cycle - } else { - CpuFreqExtendStruct.cycle = -1 - CpuFreqExtendStruct.hoverCpuFreqStruct = undefined - } - } else if (type === 'BINDER') { - binderStruct.isTableHover = tableIsHover; - if (tableIsHover) { - binderStruct.hoverCycle = cycle - } else { - binderStruct.hoverCycle = -1; - } - } - SegMenTaTion.trace.refreshCanvas(true, 'flagChange') - } - - constructor(trace: SpSystemTrace) { - SegMenTaTion.trace = trace; - } - - async init() { - let irqList = await queryIrqList(); - if (irqList.length == 0) { - return; - } - else { - await this.initFolder(); - await this.initCpuFreq(); - await this.initGpuTrace(); - await this.initSchedTrace(); - await this.initBinderTrace(); - } - } - - async initFolder() { - let row = TraceRow.skeleton(); - row.setAttribute('disabled-check', ''); - row.rowId = `segmentation`; - row.index = 0; - row.rowType = TraceRow.ROW_TYPE_SEGMENTATION; - row.rowParentId = ''; - row.folder = true; - row.style.height = '40px'; - row.name = `Segmentation`; - row.supplier = () => new Promise>((resolve) => resolve([])); - row.onThreadHandler = (useCache) => { - row.canvasSave(SegMenTaTion.trace.canvasPanelCtx!); - if (row.expansion) { - SegMenTaTion.trace.canvasPanelCtx!.clearRect(0, 0, row.frame.width, row.frame.height); - } else { - (renders['empty'] as EmptyRender).renderMainThread( - { - context: SegMenTaTion.trace.canvasPanelCtx, - useCache: useCache, - type: ``, - }, - row - ); - } - row.canvasRestore(SegMenTaTion.trace.canvasPanelCtx!); - }; - this.rowFolder = row; - SegMenTaTion.trace.rowsEL!.appendChild(row); - - } - - async initCpuFreq() { - // json文件泳道 - SegMenTaTion.jsonRow = TraceRow.skeleton(); - SegMenTaTion.jsonRow.rowId = `json0`; - SegMenTaTion.jsonRow.rowType = TraceRow.ROW_TYPE_CPU_COMPUTILITY; - SegMenTaTion.jsonRow.rowParentId = ''; - SegMenTaTion.jsonRow.style.height = '40px'; - SegMenTaTion.jsonRow.name = `Cpu Computility`; - SegMenTaTion.jsonRow.favoriteChangeHandler = SegMenTaTion.trace.favoriteChangeHandler; - SegMenTaTion.jsonRow.checkFile = 'json'; - // 拿到了用户传递的数据 - SegMenTaTion.jsonRow.onRowCheckFileChangeHandler = (e: any) => { - let chartData = JSON.parse(e); - let mapData = new Map(); - chartData.map((v: any) => { - for (let key in v.freqInfo) { - mapData.set(Number(key), v.freqInfo[key]) - } - SegMenTaTion.freqInfoMapData.set(v.cpuId, mapData) - mapData = new Map() - }) - } - SegMenTaTion.jsonRow.focusHandler = (ev) => { - SegMenTaTion.trace!.displayTip( - SegMenTaTion.jsonRow!, - CpuFreqExtendStruct.hoverCpuFreqStruct, - `${ColorUtils.formatNumberComma(CpuFreqExtendStruct.hoverCpuFreqStruct === undefined ? 0 : CpuFreqExtendStruct.hoverCpuFreqStruct.value! || 0)}` - ); - }; - SegMenTaTion.jsonRow.findHoverStruct = () => { - CpuFreqExtendStruct.hoverCpuFreqStruct = SegMenTaTion.jsonRow!.getHoverStruct(); - }; - SegMenTaTion.jsonRow.onThreadHandler = (useCache) => { - let context: CanvasRenderingContext2D; - if (SegMenTaTion.jsonRow!.currentContext) { - context = SegMenTaTion.jsonRow!.currentContext; - } else { - context = SegMenTaTion.jsonRow!.collect ? SegMenTaTion.trace.canvasFavoritePanelCtx! : SegMenTaTion.trace.canvasPanelCtx!; - } - SegMenTaTion.jsonRow!.canvasSave(context); - (renders['freq-extend'] as FreqExtendRender).renderMainThread( - { - context: context, - useCache: useCache, - type: `json0`, - }, - SegMenTaTion.jsonRow! - ); - SegMenTaTion.jsonRow!.canvasRestore(context); - }; - SegMenTaTion.trace.rowsEL!.appendChild(SegMenTaTion.jsonRow); - this.rowFolder!.addChildTraceRow(SegMenTaTion.jsonRow); - } - - async initGpuTrace() { - SegMenTaTion.GpuRow = TraceRow.skeleton(); - SegMenTaTion.GpuRow.rowId = `gpurow`; - SegMenTaTion.GpuRow.rowType = TraceRow.ROW_TYPE_GPU_COMPUTILITY; - SegMenTaTion.GpuRow.rowParentId = ''; - SegMenTaTion.GpuRow.style.height = '40px'; - SegMenTaTion.GpuRow.name = `Gpu Computility`; - SegMenTaTion.GpuRow.favoriteChangeHandler = SegMenTaTion.trace.favoriteChangeHandler; - SegMenTaTion.GpuRow.selectChangeHandler = SegMenTaTion.trace.selectChangeHandler; - SegMenTaTion.GpuRow.supplier = (): Promise> => - new Promise>((resolve) => resolve([])); - SegMenTaTion.GpuRow.focusHandler = (ev) => { - SegMenTaTion.trace!.displayTip( - SegMenTaTion.GpuRow!, - CpuFreqExtendStruct.hoverCpuFreqStruct, - `${ColorUtils.formatNumberComma(CpuFreqExtendStruct.hoverCpuFreqStruct === undefined ? 0 : CpuFreqExtendStruct.hoverCpuFreqStruct.value!)} Hz·ms` - ); - }; - SegMenTaTion.GpuRow.findHoverStruct = () => { - CpuFreqExtendStruct.hoverCpuFreqStruct = SegMenTaTion.GpuRow!.getHoverStruct(); - }; - SegMenTaTion.GpuRow.onThreadHandler = (useCache) => { - let context: CanvasRenderingContext2D; - if (SegMenTaTion.GpuRow!.currentContext) { - context = SegMenTaTion.GpuRow!.currentContext; - } else { - context = SegMenTaTion.GpuRow!.collect ? SegMenTaTion.trace.canvasFavoritePanelCtx! : SegMenTaTion.trace.canvasPanelCtx!; - } - SegMenTaTion.GpuRow!.canvasSave(context); - (renders['freq-extend'] as FreqExtendRender).renderMainThread( - { - context: context, - useCache: useCache, - type: `json0`, - }, - SegMenTaTion.GpuRow! - ); - SegMenTaTion.GpuRow!.canvasRestore(context); - }; - SegMenTaTion.trace.rowsEL!.appendChild(SegMenTaTion.GpuRow); - this.rowFolder!.addChildTraceRow(SegMenTaTion.GpuRow); - } - - async initSchedTrace() { - SegMenTaTion.schedRow = TraceRow.skeleton(); - SegMenTaTion.schedRow.rowId = `sched_switch Count`; - SegMenTaTion.schedRow.rowType = TraceRow.ROW_TYPE_SCHED_SWITCH; - SegMenTaTion.schedRow.rowParentId = ''; - SegMenTaTion.schedRow.style.height = '40px'; - SegMenTaTion.schedRow.name = `Sched_switch Count`; - SegMenTaTion.schedRow.favoriteChangeHandler = SegMenTaTion.trace.favoriteChangeHandler; - SegMenTaTion.schedRow.selectChangeHandler = SegMenTaTion.trace.selectChangeHandler; - SegMenTaTion.schedRow.focusHandler = (ev) => { - SegMenTaTion.trace!.displayTip( - SegMenTaTion.schedRow!, - CpuFreqExtendStruct.hoverCpuFreqStruct, - `${ColorUtils.formatNumberComma(CpuFreqExtendStruct.hoverCpuFreqStruct!.value!)} Hz·ms` - ); - }; - SegMenTaTion.schedRow.findHoverStruct = () => { - CpuFreqExtendStruct.hoverCpuFreqStruct = SegMenTaTion.schedRow!.getHoverStruct(); - }; - SegMenTaTion.schedRow.supplier = (): Promise> => - new Promise>((resolve) => resolve([])); - SegMenTaTion.schedRow.onThreadHandler = (useCache) => { - let context: CanvasRenderingContext2D; - if (SegMenTaTion.schedRow!.currentContext) { - context = SegMenTaTion.schedRow!.currentContext; - } else { - context = SegMenTaTion.schedRow!.collect ? SegMenTaTion.trace.canvasFavoritePanelCtx! : SegMenTaTion.trace.canvasPanelCtx!; - } - SegMenTaTion.schedRow!.canvasSave(context); - (renders['freq-extend'] as FreqExtendRender).renderMainThread( - { - context: context, - useCache: useCache, - type: `json0`, - }, - SegMenTaTion.schedRow! - ); - SegMenTaTion.schedRow!.canvasRestore(context); - }; - SegMenTaTion.trace.rowsEL!.appendChild(SegMenTaTion.schedRow); - this.rowFolder!.addChildTraceRow(SegMenTaTion.schedRow); - } - - async initBinderTrace() { - SegMenTaTion.binderRow = TraceRow.skeleton(); - SegMenTaTion.binderRow.rowId = `binderrow`; - SegMenTaTion.binderRow.rowType = TraceRow.ROW_TYPE_BINDER_COUNT; - SegMenTaTion.binderRow.rowParentId = ''; - SegMenTaTion.binderRow.name = `Binder Count`; - SegMenTaTion.binderRow.style.height = '40px'; - SegMenTaTion.binderRow.favoriteChangeHandler = SegMenTaTion.trace.favoriteChangeHandler; - SegMenTaTion.binderRow.selectChangeHandler = SegMenTaTion.trace.selectChangeHandler; - SegMenTaTion.binderRow.focusHandler = (ev) => { - SegMenTaTion.trace!.displayTip( - SegMenTaTion.binderRow!, - binderStruct.hoverCpuFreqStruct, - `Cycle: ${binderStruct.hoverCpuFreqStruct!.cycle}
    - Name: ${binderStruct.hoverCpuFreqStruct!.name || ''}
    - Count: ${binderStruct.hoverCpuFreqStruct!.value || ''}` - ); - }; - SegMenTaTion.binderRow.findHoverStruct = () => { - binderStruct.hoverCpuFreqStruct = SegMenTaTion.binderRow!.dataListCache.find((v: any) => { - if (SegMenTaTion.binderRow!.isHover) { - if (v.frame.x < SegMenTaTion.binderRow.hoverX - && v.frame.x + v.frame.width > SegMenTaTion.binderRow.hoverX - && (binderStruct.maxHeight * 20 - v.depth * 20 + 20) < SegMenTaTion.binderRow!.hoverY - && binderStruct.maxHeight * 20 - v.depth * 20 + v.value * 20 + 20 > SegMenTaTion.binderRow!.hoverY) { - console - return v - } - } - }) - }; - SegMenTaTion.binderRow.supplier = (): Promise> => - new Promise>((resolve) => resolve([])); - SegMenTaTion.binderRow.onThreadHandler = (useCache) => { - let context: CanvasRenderingContext2D; - if (SegMenTaTion.binderRow!.currentContext) { - context = SegMenTaTion.binderRow!.currentContext; - } else { - context = SegMenTaTion.binderRow!.collect ? SegMenTaTion.trace.canvasFavoritePanelCtx! : SegMenTaTion.trace.canvasPanelCtx!; - } - SegMenTaTion.binderRow!.canvasSave(context); - (renders['binder'] as BinderRender).renderMainThread( - { - context: context, - useCache: useCache, - type: `binder`, - }, - SegMenTaTion.binderRow! - ); - SegMenTaTion.binderRow!.canvasRestore(context); - }; - SegMenTaTion.trace.rowsEL!.appendChild(SegMenTaTion.binderRow); - this.rowFolder!.addChildTraceRow(SegMenTaTion.binderRow); - } -} diff --git a/ide/src/trace/component/setting/SpHilogRecord.ts b/ide/src/trace/component/setting/SpHilogRecord.ts index ef1bb665b..fbb07bd80 100644 --- a/ide/src/trace/component/setting/SpHilogRecord.ts +++ b/ide/src/trace/component/setting/SpHilogRecord.ts @@ -55,6 +55,7 @@ export class SpHilogRecord extends BaseElement { configVisibility = 'block'; } if (hiLogConfigList) { + console.log(configVisibility); hiLogConfigList!.forEach(configEl => { configEl.style.display = configVisibility; }); diff --git a/ide/src/trace/component/trace/SpChartList.ts b/ide/src/trace/component/trace/SpChartList.ts index 6e8e14a2a..c95af098f 100644 --- a/ide/src/trace/component/trace/SpChartList.ts +++ b/ide/src/trace/component/trace/SpChartList.ts @@ -350,6 +350,7 @@ export class SpChartList extends BaseElement { this.fragmentGroup1.appendChild(row); } this.collectEl1?.appendChild(this.fragmentGroup1); + this.scrollTo({ top: this.collectEl1?.clientHeight || 0 }); } else { if (!this.collect2Expand) { this.collect2Expand = true; @@ -362,10 +363,10 @@ export class SpChartList extends BaseElement { this.fragmentGroup2.appendChild(row); } this.collectEl2!.appendChild(this.fragmentGroup2); + this.scrollTo({ top: this.scrollHeight }); } this.updateGroupDisplay(); this.resizeHeight(); - this.scrollTo({ top: this.scrollHeight }); this.refreshFavoriteCanvas(); row.currentContext = this.canvasCtx; } diff --git a/ide/src/trace/component/trace/base/TraceRow.ts b/ide/src/trace/component/trace/base/TraceRow.ts index 07de4e950..df8041dc4 100644 --- a/ide/src/trace/component/trace/base/TraceRow.ts +++ b/ide/src/trace/component/trace/base/TraceRow.ts @@ -44,11 +44,6 @@ let dragDirection: string = ''; @element('trace-row') export class TraceRow extends HTMLElement { - static ROW_TYPE_SEGMENTATION = 'segmentation'; - static ROW_TYPE_CPU_COMPUTILITY = 'cpu_computility'; - static ROW_TYPE_GPU_COMPUTILITY = 'gpu_computility'; - static ROW_TYPE_SCHED_SWITCH = 'sched_switch'; - static ROW_TYPE_BINDER_COUNT = 'binder'; static ROW_TYPE_CPU = 'cpu-data'; static ROW_TYPE_CPU_STATE = 'cpu-state'; static ROW_TYPE_CPU_FREQ = 'cpu-freq'; @@ -122,7 +117,6 @@ export class TraceRow extends HTMLElement { static ROW_TYPE_PURGEABLE_TOTAL_VM = 'purgeable-total-vm'; static ROW_TYPE_PURGEABLE_PIN_VM = 'purgeable-pin-vm'; static ROW_TYPE_LOGS = 'logs'; - static ROW_TYPE_ALL_APPSTARTUPS = 'all-appstartups' static FRAME_WIDTH: number = 0; static range: TimeRange | undefined | null; static rangeSelectObject: RangeSelectStruct | undefined; @@ -179,9 +173,6 @@ export class TraceRow extends HTMLElement { parentRowEl: TraceRow | undefined; _rowSettingList: Array | null | undefined; _docompositionList: Array | undefined; - public rowCheckFileEL: LitIcon | null | undefined; - public inputEL: any; - public onRowCheckFileChangeHandler: ((file: any) => void) | undefined | null; focusHandler?: (ev: MouseEvent) => void | undefined; findHoverStruct?: () => void | undefined; @@ -196,12 +187,12 @@ export class TraceRow extends HTMLElement { isOffScreen: boolean; skeleton?: boolean; } = { - canvasNumber: 1, - alpha: false, - contextId: '2d', - isOffScreen: true, - skeleton: false, - } + canvasNumber: 1, + alpha: false, + contextId: '2d', + isOffScreen: true, + skeleton: false, + } ) { super(); this.args = args; @@ -243,15 +234,6 @@ export class TraceRow extends HTMLElement { 'row-setting-popover-direction', ]; } - - get checkFile(): string { - return this.getAttribute('row-file') || 'disable' - } - - set checkFile(value: string) { - this.setAttribute('row-file', value) - } - get docompositionList(): Array | undefined { return this._docompositionList; } @@ -674,8 +656,6 @@ export class TraceRow extends HTMLElement { this.canvasVessel = this.shadowRoot?.querySelector('.panel-vessel'); this.tipEL = this.shadowRoot?.querySelector('.tip'); let canvasNumber = this.args['canvasNumber']; - this.rowCheckFileEL = this.shadowRoot?.querySelector('.checkfile'); - this.inputEL = this.shadowRoot?.querySelector('#fileinput'); if (!this.args['skeleton']) { for (let i = 0; i < canvasNumber; i++) { let canvas = document.createElement('canvas'); @@ -686,24 +666,6 @@ export class TraceRow extends HTMLElement { } } } - - this.rowCheckFileEL!.onclick = () => { - this.inputEL.click(); - this.inputEL.addEventListener('change', (e: any) => { - let file = e.target.files[0]; - if (file.type === 'application/json') { - let file_reader = new FileReader(); - file_reader.readAsText(file, 'UTF-8'); - file_reader.onload = () => { - let fc = file_reader.result; - this.onRowCheckFileChangeHandler?.(fc) - }; - } else { - return - } - }, false) - } - this.checkBoxEL!.onchange = (ev: any) => { info('checkBoxEL onchange '); if (!ev.target.checked) { @@ -730,7 +692,7 @@ export class TraceRow extends HTMLElement { this.checkType = '-1'; } - addRowSettingPop(): void { + addRowSettingPop(): void{ this.rowSettingPop = document.createElement('lit-popover') as LitPopover; this.rowSettingPop.innerHTML = `
    @@ -759,7 +721,7 @@ export class TraceRow extends HTMLElement { this.describeEl?.appendChild(this.rowSettingPop); } - getRowSettingKeys(): Array { + getRowSettingKeys() : Array { if (this.rowSetting === 'enable') { return this.rowSettingTree!.getCheckdKeys(); } @@ -778,7 +740,7 @@ export class TraceRow extends HTMLElement { } } - enableCollapseChart(): void { + enableCollapseChart() : void { this._enableCollapseChart = true; this.nameEL!.onclick = () => { if (this.funcExpand) { @@ -1458,34 +1420,14 @@ export class TraceRow extends HTMLElement { :host([row-setting='enable']:not([check-type='-1'])) .collect{ margin-right: 5px; } - :host(:not([row-file='json'])) .checkfile{ - display:none; - } - :host(:not([row-file='json'])) input{ - display:none; - } - :host([row-file='json']) .checkfile{ - display:flex; - } - :host([row-file='json']) input{ - display:flex; - } - :host([row-file='json']) .folder{ - display:none; - } - :host([row-file="json"]) .describe:hover .checkfile{ - color:#000; - }
    -
    -
    `; } diff --git a/ide/src/trace/component/trace/base/TraceSheet.ts b/ide/src/trace/component/trace/base/TraceSheet.ts index 8a93da17a..4ccf1157b 100644 --- a/ide/src/trace/component/trace/base/TraceSheet.ts +++ b/ide/src/trace/component/trace/base/TraceSheet.ts @@ -42,7 +42,6 @@ import { type TabPaneNMStatisticAnalysis } from '../sheet/native-memory/TabPaneN import { type TabPaneCurrent } from '../sheet/TabPaneCurrent.js'; import { type SlicesTime } from '../timer-shaft/SportRuler.js'; import { type AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAppStartup.js'; -import { type AllAppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAllAppStartup.js'; import { type SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit.js'; import { type FrameAnimationStruct } from '../../../database/ui-worker/ProcedureWorkerFrameAnimation.js'; import { type TraceRow } from './TraceRow.js'; @@ -82,7 +81,6 @@ import { type LitPageTable } from '../../../../base-ui/table/LitPageTable.js'; import '../../../../base-ui/popover/LitPopoverV.js'; import { LitPopover } from '../../../../base-ui/popover/LitPopoverV.js'; import { LitTree, TreeItemData } from '../../../../base-ui/tree/LitTree.js'; -import { SegMenTaTion } from '../../chart/SpSegmentationChart.js'; @element('trace-sheet') export class TraceSheet extends BaseElement { @@ -284,7 +282,7 @@ export class TraceSheet extends BaseElement { } else if ( navRoot!.offsetHeight <= moveY && search!.offsetHeight + timerShaft!.offsetHeight + borderTop + spacer!.offsetHeight <= - window.innerHeight - moveY + window.innerHeight - moveY ) { tabs!.style.height = moveY + 'px'; node!.style.height = moveY - navRoot!.offsetHeight + 'px'; @@ -483,16 +481,14 @@ export class TraceSheet extends BaseElement { scrollCallback: ((e: ThreadStruct) => void) | undefined, scrollWakeUp: (d: any) => void | undefined, scrollPreviousData: (d: ThreadStruct) => void, - scrollNextData: (d: ThreadStruct) => void, - callback: ((data: Array) => void) | undefined = undefined, + scrollNextData: (d: ThreadStruct) => void ) => this.displayTab('current-selection').setThreadData( data, scrollCallback, scrollWakeUp, scrollPreviousData, - scrollNextData, - callback + scrollNextData ); displayMemData = (data: ProcessMemStruct): void => this.displayTab('current-selection').setMemData(data); @@ -502,8 +498,6 @@ export class TraceSheet extends BaseElement { this.displayTab('current-selection').setIrqData(data); displayStartupData = (data: AppStartupStruct, scrollCallback: Function): void => this.displayTab('current-selection').setStartupData(data, scrollCallback); - displayAllStartupData = (data: AllAppStartupStruct, scrollCallback: Function): void => - this.displayTab('current-selection').setAllStartupData(data, scrollCallback); displayStaticInitData = (data: SoStruct, scrollCallback: Function): void => this.displayTab('current-selection').setStaticInitData(data, scrollCallback); @@ -808,9 +802,9 @@ export class TraceSheet extends BaseElement { if (selection && selection.nativeMemoryAllProcess.length > 1) { this.switchDiv!.style.display = 'flex'; if (this.isProcessEqual(selection.nativeMemoryAllProcess)) { - if (this.processTree) { - for (const data of this.processTree.treeData) { - if (data.key === `${selection.nativeMemoryCurrentIPid}`) { + if (this.processTree){ + for (const data of this.processTree.treeData){ + if (data.key === `${selection.nativeMemoryCurrentIPid}`){ data.checked = true; } else { data.checked = false; @@ -844,11 +838,10 @@ export class TraceSheet extends BaseElement { } loadTabPaneData(key: string): void { - SegMenTaTion.setChartData('BINDER',[]); let component: any = this.shadowRoot ?.querySelector(`#tabs lit-tabpane[key='${key}']`) ?.children.item(0); - if (component) { + if (component) { this.selection!.isRowClick = false; component.data = this.selection; } diff --git a/ide/src/trace/component/trace/base/TraceSheetConfig.ts b/ide/src/trace/component/trace/base/TraceSheetConfig.ts index dd7810ba8..ff0f3522d 100644 --- a/ide/src/trace/component/trace/base/TraceSheetConfig.ts +++ b/ide/src/trace/component/trace/base/TraceSheetConfig.ts @@ -122,11 +122,6 @@ import { TabPaneFreqUsage } from '../sheet/frequsage/TabPaneFreqUsage.js'; import { TabPaneFreqDataCut } from '../sheet/frequsage/TabPaneFreqDataCut.js'; import { TabPaneHisysEvents } from '../sheet/hisysevent/TabPaneHisysEvents.js'; import { TabPaneHiSysEventSummary } from '../sheet/hisysevent/TabPaneHiSysEventSummary.js'; -import {TabPaneSchedSwitch} from '../sheet/schedswitch/TabPaneSchedSwitch.js'; -import { TabPaneThreadBinders } from '../sheet/binder/TabPaneThreadBinders.js'; -import { TabPaneBinderDataCut } from '../sheet/binder/TabPaneBinderDataCut.js'; -import {TabPaneGpufreq} from '../sheet/gpufreq/tabPaneGpufreqUsage.js' -import {TabPaneGpufreqDataCut} from '../sheet/gpufreq/tabPaneGpufreqDataCut.js' export let tabConfig: any = { 'current-selection': { @@ -655,28 +650,4 @@ export let tabConfig: any = { type: TabPaneHiSysEventSummary, require: (param: SelectionParam) => param.hiSysEvents.length > 0, }, - 'tabpane-schedswitch': { - title: 'Sched Switch', - type: TabPaneSchedSwitch, - require: (param: SelectionParam) => param.threadIds.length > 0, - 'tabpane-Thrbinders': { - title: 'Thread Binders', - type: TabPaneThreadBinders, - require: (param: SelectionParam) => param.threadIds.length > 0 - }, - 'tabpane-Thrfreqdatacut': { - title: 'Binder DataCut', - type: TabPaneBinderDataCut, - require: (param: SelectionParam) => param.threadIds.length > 0 - }, - 'tabpane-Gpufreq':{ - title: 'Gpufreq Usage', - type: TabPaneGpufreq, - require: (param: SelectionParam) => param.clockMapData.size > 0 && param.clockMapData.size < 2, - }, - 'tabpane-FreqDataCut':{ - title: 'Gpufreq DataCut', - type: TabPaneGpufreqDataCut, - require: (param: SelectionParam) => param.clockMapData.size > 0 && param.clockMapData.size < 2, - } }; diff --git a/ide/src/trace/component/trace/base/Utils.ts b/ide/src/trace/component/trace/base/Utils.ts index 0728af026..12cbe7751 100644 --- a/ide/src/trace/component/trace/base/Utils.ts +++ b/ide/src/trace/component/trace/base/Utils.ts @@ -97,20 +97,6 @@ export class Utils { } } - public static transferBinderTitle(value: any) { - if (value.startsWith('P-')) { - let pid = value.replace('P-', ''); - let process = Utils.PROCESS_MAP.get(parseInt(pid)) || 'Process'; - return `${process} [${pid}]`; - } else if (value.startsWith('T-')) { - let tid = value.replace('T-', ''); - let thread = Utils.THREAD_MAP.get(parseInt(tid)) || 'Thread'; - return `${thread} [${tid}]`; - } else { - return ''; - } - } - public static getStateColor(state: string): string { if (state === 'D-NIO' || state === 'DK-NIO') { return '#795548'; @@ -497,11 +483,11 @@ export class Utils { } } queryNativeHookResponseTypes(val.leftNs, val.rightNs, types, isStatistic).then((res) => { - procedurePool.submitWithName('logic1', 'native-memory-init-responseType', res, undefined, () => { }); + procedurePool.submitWithName('logic1', 'native-memory-init-responseType', res, undefined, () => {}); }); } - setCurrentSelectIPid(ipid: number): void { - procedurePool.submitWithName('logic1', 'native-memory-set-current_ipid', ipid, undefined, () => { }); + setCurrentSelectIPid(ipid: number): void{ + procedurePool.submitWithName('logic1', 'native-memory-set-current_ipid', ipid, undefined, () => {}); } } diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts index 76bf1e19e..cb064fd5c 100644 --- a/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts +++ b/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts @@ -33,7 +33,7 @@ export class TabPaneCurrent extends BaseElement { this.systemTrace = document .querySelector('body > sp-application') ?.shadowRoot!.querySelector('#sp-system-trace'); - this.shadowRoot?.querySelector('#text')?.addEventListener('keyup', (event: any) => { + this.shadowRoot?.querySelector('#text')?.addEventListener('keyup', (event: any) => { event.stopPropagation(); if (event.keyCode == '13') { if (this.slicesTime) { @@ -60,7 +60,7 @@ export class TabPaneCurrent extends BaseElement { window.publish(window.SmartEvent.UI.KeyboardEnable, { enable: false, }); - }); + }); this.panelTable = this.shadowRoot!.querySelector('.notes-editor-panel'); this.panelTable!.addEventListener('row-click', (evt: any) => { if (evt.detail.data.startTime === undefined) { @@ -176,7 +176,6 @@ export class TabPaneCurrent extends BaseElement { */ private eventHandler(): void { let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf; - tr[0].querySelector('#text-input')!.disabled = true; tr[0].querySelector('.removeAll')!.addEventListener('click', (evt: any) => { this.systemTrace!.slicesList = []; let slicesTimeList = [...this.slicesTimeList]; @@ -186,13 +185,13 @@ export class TabPaneCurrent extends BaseElement { } this.slicesTimeList = []; return; - }); + }); // 更新备注信息 this.panelTable!.addEventListener('click', (event: any) => { if (this.slicesTimeList.length === 0) { return; - } + } for (let i = 1; i < tr.length; i++) { let inputValue = tr[i].querySelector('#text-input')!.value; if ( diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts index a0b979d9c..f57ea33ea 100644 --- a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts +++ b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts @@ -49,7 +49,6 @@ import { AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerApp import { SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit.js'; import { type SelectionParam } from '../../../bean/BoxSelection.js'; import { type FrameAnimationStruct } from '../../../database/ui-worker/ProcedureWorkerFrameAnimation.js'; -import { AllAppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAllAppStartup.js'; const INPUT_WORD = 'This is the interval from when the task became eligible to run \n(e.g.because of notifying a wait queue it was a suspended on) to\n when it started running.'; @@ -456,8 +455,7 @@ export class TabPaneCurrentSelection extends BaseElement { scrollCallback: ((d: any) => void) | undefined, scrollWakeUp: (d: any) => void | undefined, scrollPreviousData: (d: any) => void | undefined, - scrollNextData: (d: any) => void | undefined, - callback: ((data: Array) => void) | undefined = undefined + scrollNextData: (d: any) => void | undefined ): void { //线程信息 this.setTableHeight('550px'); @@ -468,7 +466,6 @@ export class TabPaneCurrentSelection extends BaseElement { leftTitle.innerText = 'Thread State'; } let list: any[] = []; - let jankJumperList = new Array(); list.push({ name: 'StartTime(Relative)', value: getTimeString(data.startTime || 0), @@ -586,17 +583,12 @@ export class TabPaneCurrentSelection extends BaseElement { }); }); } - let timeLineNode = new ThreadTreeNode(data.tid!, data.pid!, data.startTime!); - jankJumperList.push(timeLineNode); if (args.length > 0) { args.forEach((arg) => { list.push({ name: arg.keyName, value: arg.strValue }); }); } this.currentSelectionTbl!.dataSource = list; - if (callback) { - callback(jankJumperList); - } this.currentSelectionTbl?.shadowRoot?.querySelector('#next-state-click')?.addEventListener('click', () => { if (scrollNextData) { scrollNextData(data); @@ -823,41 +815,6 @@ export class TabPaneCurrentSelection extends BaseElement { this.currentSelectionTbl!.dataSource = list; } } - setAllStartupData(data: AllAppStartupStruct, scrollCallback: Function): void { - this.setTableHeight('550px'); - this.initCanvas(); - let allStartUpLeftTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#leftTitle'); - let allStartUpmiddleTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightText'); - let allStartUpRightButton: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightButton'); - if (allStartUpmiddleTitle) allStartUpmiddleTitle.style.visibility = 'hidden'; - if (allStartUpRightButton) allStartUpRightButton.style.visibility = 'hidden'; - if (allStartUpLeftTitle) { - allStartUpLeftTitle.innerText = 'Details'; - } - let list: any[] = []; - list.push({ name: "Name", value: data.stepName! }) - list.push({ - name: "StartTime(Relative)", - value: getTimeString(data.startTs || 0) - }); - list.push({ - name: "StartTime(Absolute)", - value: ((data.startTs || 0) + (window as any).recordStartNS) / 1000000000 + 's' - }); - list.push({ - name: "EndTime(Relative)", - value: getTimeString((data.startTs || 0) + (data.dur || 0)) - }); - list.push({ - name: "EndTime(Abslute)", - value: ((data.startTs || 0) + (data.dur || 0) + (window as any).recordStartNS) / 1000000000 + 's' - }) - list.push({ - name: "Dur", - value: getTimeString(data.dur || 0) - }) - this.currentSelectionTbl!.dataSource = list; - } setStartupData(data: AppStartupStruct, scrollCallback: Function): void { this.setTableHeight('550px'); @@ -1267,7 +1224,7 @@ export class TabPaneCurrentSelection extends BaseElement { this.currentSelectionTbl = this.shadowRoot?.querySelector('#selectionTbl'); this.wakeupListTbl = this.shadowRoot?.querySelector('#wakeupListTbl'); this.scrollView = this.shadowRoot?.querySelector('#scroll_view'); - this.currentSelectionTbl?.addEventListener('column-click', (ev: any) => { }); + this.currentSelectionTbl?.addEventListener('column-click', (ev: any) => {}); window.subscribe(window.SmartEvent.UI.WakeupList, (data: Array) => this.showWakeupListTableData(data)); } @@ -1451,14 +1408,3 @@ export class JankTreeNode { children: Array = []; } - -export class ThreadTreeNode { - tid: number = 0; - pid: number = -1; - startTime: number = 1; - constructor(tid: number, pid: number, startTime: number) { - this.tid = tid; - this.pid = pid; - this.startTime = startTime; - } -} diff --git a/ide/src/trace/component/trace/sheet/binder/TabPaneBinderDataCut.ts b/ide/src/trace/component/trace/sheet/binder/TabPaneBinderDataCut.ts deleted file mode 100644 index e3cbaa9c9..000000000 --- a/ide/src/trace/component/trace/sheet/binder/TabPaneBinderDataCut.ts +++ /dev/null @@ -1,781 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; -import { Utils } from '../../base/Utils.js'; -import { SelectionParam } from '../../../../bean/BoxSelection'; -import { BinderGroup, DataSource, FuncNameCycle, BinderColumn } from '../../../../bean/BinderProcessThread.js'; -import { querySingleFuncNameCycle, queryBinderByThreadId, queryLoopFuncNameCycle } from '../../../../database/SqlLite.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { LitChartColumn } from '../../../../../base-ui/chart/column/LitChartColumn.js'; -import '../../../../../base-ui/chart/column/LitChartColumn.js'; -// import { SegMenTaTion } from '../../../chart/SpSegmentationChart.js'; - -@element('tabpane-binder-datacut') -export class TabPaneBinderDataCut extends BaseElement { - private threadBindersTbl: LitTable | null | undefined; - private currentSelectionParam: SelectionParam | any; - private threadStatesDIV: Element | null | undefined; - private cycleARangeArr: BinderGroup[] | undefined; - private cycleBRangeArr: BinderGroup[] | undefined; - private cycleAStartRangeDIV: HTMLInputElement | null | undefined; - private cycleAEndRangeDIV: HTMLInputElement | null | undefined; - private cycleBStartRangeDIV: HTMLInputElement | null | undefined; - private cycleBEndRangeDIV: HTMLInputElement | null | undefined; - private chartTotal: LitChartColumn | null | undefined; - private dataSource: DataSource[] | undefined; - private rowCycleData: BinderGroup[] | undefined; - private funcNameCycleArr: FuncNameCycle[] | undefined; - private cacheBinderArr: BinderGroup[] | undefined; - private currentThreadId: string | undefined; - - set data(threadStatesParam: SelectionParam | any) { - let threadIdDIV = this.shadowRoot!.querySelector('.thread-id-input') as HTMLElement; - threadIdDIV.style.border = '1px solid rgb(151,151,151)'; - let cycleNameDIV = this.shadowRoot!.querySelector('.cycle-name-input') as HTMLElement; - cycleNameDIV.style.border = '1px solid rgb(151,151,151)'; - if (this.currentSelectionParam === threadStatesParam) { - return; - } - this.dispalyQueryArea(true); - this.clickLoop(false); - this.clickSingle(false); - this.currentSelectionParam = threadStatesParam; - this.threadBindersTbl!.recycleDataSource = []; - this.theadClick(this.threadBindersTbl!.recycleDataSource); - } - - dispalyQueryArea(b: boolean) { - if (b) { - this.setAttribute('dispalyQueryArea', ''); - } else { - this.removeAttribute('dispalyQueryArea'); - } - } - - clickSingle(b: boolean) { - if (b) { - this.setAttribute('clickSingle', ''); - } else { - this.removeAttribute('clickSingle'); - } - } - - clickLoop(b: boolean) { - if (b) { - this.setAttribute('clickLoop', ''); - } else { - this.removeAttribute('clickLoop'); - } - } - - async dataLoopCut(threadId: HTMLInputElement, threadFunc: HTMLInputElement) { - this.currentThreadId = ''; - let threadIds = this.currentSelectionParam.threadIds; - let processIds = this.currentSelectionParam.processIds; - let threadIdValue = threadId.value.trim(); - let threadFuncName = threadFunc.value.trim(); - let leftNS = this.currentSelectionParam.leftNs; - let rightNS = this.currentSelectionParam.rightNs; - if (threadIdValue != '' && threadFuncName != '') { - // SegMenTaTion.setChartData("BINDER", []); - this.clickLoop(true); - this.clickSingle(false); - this.threadBindersTbl!.loading = true; - threadId.style.border = '1px solid rgb(151,151,151)'; - threadFunc.style.border = '1px solid rgb(151,151,151)'; - this.funcNameCycleArr = await queryLoopFuncNameCycle(threadFuncName, threadIdValue, leftNS, rightNS); - let binderArr = await queryBinderByThreadId(processIds, threadIds, leftNS, rightNS); - if (this.funcNameCycleArr.length !== 0) { - let binderCutArr = []; - for (let j = 0; j < this.funcNameCycleArr.length - 1; j++) { - this.funcNameCycleArr[j].cycleDur = this.funcNameCycleArr[j + 1].cycleStartTime - this.funcNameCycleArr[j].cycleStartTime; - for (let i = 0; i < binderArr.length; i++) { - if (binderArr[i].ts > this.funcNameCycleArr[j].cycleStartTime - && binderArr[i].ts + binderArr[i].dur < this.funcNameCycleArr[j + 1].cycleStartTime) { - // calculate cycle duration - binderArr[i].cycleDur = this.funcNameCycleArr[j + 1].cycleStartTime - this.funcNameCycleArr[j].cycleStartTime; - binderArr[i].cycleStartTime = this.funcNameCycleArr[j].cycleStartTime; - binderArr[i].funcName = this.funcNameCycleArr[j].funcName; - binderArr[i].id = this.funcNameCycleArr[j].id; - binderArr[i].thread = Utils.THREAD_MAP.get(binderArr[i].tid) || 'Thread'; - binderArr[i].process = Utils.PROCESS_MAP.get(binderArr[i].pid) || 'Process'; - binderArr[i].count = 1; - binderCutArr.push(binderArr[i]); - } - } - } - let finalCutBinderArr = this.completionCycleName(binderCutArr, 'loop'); - this.threadBindersTbl!.recycleDataSource = this.transferToTreeData(finalCutBinderArr); - this.threadBindersTbl!.loading = false; - this.theadClick(this.threadBindersTbl!.recycleDataSource); - } else { - this.threadBindersTbl!.recycleDataSource = []; - this.threadBindersTbl!.loading = false; - this.theadClick(this.threadBindersTbl!.recycleDataSource); - } - } else { - if (threadIdValue == '') { - threadId.style.border = '1px solid rgb(255,0,0)'; - threadId.setAttribute('placeholder', 'Please input thread id'); - } else { - threadId.style.border = '1px solid rgb(151,151,151)'; - } - - if (threadFuncName == '') { - threadFunc.style.border = '1px solid rgb(255,0,0)'; - threadFunc.setAttribute('placeholder', 'Please input function name'); - } else { - threadFunc.style.border = '1px solid rgb(151,151,151)'; - } - } - } - - async dataSingleCut(threadId: HTMLInputElement, threadFunc: HTMLInputElement) { - this.currentThreadId = ''; - let threadIds = this.currentSelectionParam.threadIds; - let processIds = this.currentSelectionParam.processIds; - let threadIdValue = threadId.value.trim(); - let threadFuncName = threadFunc.value.trim(); - let leftNS = this.currentSelectionParam.leftNs; - let rightNS = this.currentSelectionParam.rightNs; - if (threadIdValue != '' && threadFuncName != '') { - // SegMenTaTion.setChartData("BINDER", []); - this.clickLoop(false); - this.clickSingle(true); - threadId.style.border = '1px solid rgb(151,151,151)'; - threadFunc.style.border = '1px solid rgb(151,151,151)'; - this.threadBindersTbl!.loading = true; - this.funcNameCycleArr = await querySingleFuncNameCycle(threadFuncName, threadIdValue, leftNS, rightNS); - let binderArr = await queryBinderByThreadId(processIds, threadIds, leftNS, rightNS); - if (this.funcNameCycleArr.length !== 0) { - let binderCutArr: BinderGroup[] = []; - for (let j = 0; j < this.funcNameCycleArr.length; j++) { - for (let i = 0; i < binderArr.length; i++) { - if (binderArr[i].ts > this.funcNameCycleArr[j].cycleStartTime - && binderArr[i].ts + binderArr[i].dur < this.funcNameCycleArr[j].cycleStartTime + this.funcNameCycleArr[j]!.cycleDur) { - binderArr[i].cycleDur = this.funcNameCycleArr[j].cycleDur; - binderArr[i].cycleStartTime = this.funcNameCycleArr[j].cycleStartTime; - binderArr[i].funcName = this.funcNameCycleArr[j].funcName; - binderArr[i].id = this.funcNameCycleArr[j].id; - binderArr[i].thread = Utils.THREAD_MAP.get(binderArr[i].tid) || 'Thread'; - binderArr[i].process = Utils.PROCESS_MAP.get(binderArr[i].pid) || 'Process'; - binderArr[i].count = 1; - binderCutArr.push(binderArr[i]); - } - } - } - - let finalCutBinderArr = this.completionCycleName(binderCutArr, 'single'); - this.threadBindersTbl!.recycleDataSource = this.transferToTreeData(finalCutBinderArr); - this.threadBindersTbl!.loading = false; - this.theadClick(this.threadBindersTbl!.recycleDataSource); - } else { - this.threadBindersTbl!.recycleDataSource = []; - this.threadBindersTbl!.loading = false; - this.theadClick(this.threadBindersTbl!.recycleDataSource); - } - } else { - if (threadIdValue == '') { - threadId.style.border = '1px solid rgb(255,0,0)'; - threadId.setAttribute('placeholder', 'Please input thread id'); - } else { - threadId.style.border = '1px solid rgb(151,151,151)'; - } - - if (threadFuncName == '') { - threadFunc.style.border = '1px solid rgb(255,0,0)'; - threadFunc.setAttribute('placeholder', 'Please input function name'); - } else { - threadFunc.style.border = '1px solid rgb(151,151,151)'; - } - } - } - - completionCycleName(binderCutArr: BinderGroup[], type: string): BinderGroup[] { - let threadIds: number[] = this.currentSelectionParam.threadIds; - let threadBinderCutArr: BinderGroup[][] = []; - let childThreadbinderCutArr: BinderGroup[] = []; - threadIds.forEach((tid: number, i: number) => { - childThreadbinderCutArr = []; - binderCutArr.forEach((binder: BinderGroup) => { - if (binder.tid === tid) { - childThreadbinderCutArr.push(binder) - } - }) - if (childThreadbinderCutArr.length > 0) { - threadBinderCutArr.push(childThreadbinderCutArr); - } - }) - // loop data cut need delete last function Name cycle data - if (type === 'loop') { - this.funcNameCycleArr?.pop(); - } - let cloneThreadBinderCutArr: BinderGroup[][] = JSON.parse(JSON.stringify(threadBinderCutArr)); - let binderContainsFuncIdArr: any = []; - threadBinderCutArr.forEach((binderArr: BinderGroup[], idx: number) => { - binderArr.forEach((binder: BinderGroup) => { - if (!binderContainsFuncIdArr.includes(binder.id)) { - binderContainsFuncIdArr.push(binder.id); - } - }) - // When the cycle data is incomplete - if (this.funcNameCycleArr!.length !== binderContainsFuncIdArr.length) { - this.completionAllFname(binderContainsFuncIdArr, idx, cloneThreadBinderCutArr); - } - binderContainsFuncIdArr = []; - }) - cloneThreadBinderCutArr.forEach(arr => { - arr.sort(this.compare('id')); - }) - return cloneThreadBinderCutArr.flat(); - } - - completionAllFname(binderContainsFuncIdArr: number[], idx: number, cloneThreadBinderCutArr: BinderGroup[][]) { - this.funcNameCycleArr!.forEach((it: FuncNameCycle) => { - if (!binderContainsFuncIdArr.includes(it.id)) { - let itemData = cloneThreadBinderCutArr[idx][0]; - let item: BinderGroup = { - title: '', - count: 0, - totalCount: 0, - cycleDur: it.cycleDur, - cycleStartTime: it.cycleStartTime, - id: it.id, - name: '', - pid: itemData.pid, - process: itemData.process, - thread: itemData.thread, - tid: itemData.tid, - idx: 0 - } - cloneThreadBinderCutArr[idx].push(item); - } - }) - } - - compare(prop: string) { - return function (obj1: any, obj2: any) { - let val1 = obj1[prop]; - let val2 = obj2[prop]; - if (val1 < val2) { - return -1; - } else if (val1 > val2) { - return 1; - } else { - return 0; - } - } - } - - transferToTreeData(binderList: Array): Array { - let group: any = {}; - binderList.forEach((it: BinderGroup) => { - let cycleItem = { - title: it.thread + ' ' + '[' + it.tid + ']' + '[' + it.id + ']', - totalCount: it.count, - binderTransactionCount: it.name == 'binder transaction' ? it.count : 0, - binderAsyncRcvCount: it.name == 'binder async rcv' ? it.count : 0, - binderReplyCount: it.name == 'binder reply' ? it.count : 0, - binderTransactionAsyncCount: it.name == 'binder transaction async' ? it.count : 0, - tid: it.tid, - pid: it.pid, - thread: it.thread, - cycleDur: it.cycleDur || 0, - cycleStartTime: it.cycleStartTime, - type: 'cycle', - }; - if (group[`${it.pid}`]) { - let process = group[`${it.pid}`]; - process.totalCount += it.count; - let thread = process.children.find((child: BinderGroup) => child.title === it.thread + ' ' + '[' + it.tid + ']'); - if (thread) { - thread.totalCount += it.count; - let cycle = thread.children.find((child: BinderGroup) => child.title === it.thread + ' ' + '[' + it.tid + ']' + '[' + it.id + ']'); - if (cycle) { - cycle.totalCount += it.count; - cycle.binderTransactionCount += it.name == 'binder transaction' ? it.count : 0; - cycle.binderAsyncRcvCount += it.name == 'binder async rcv' ? it.count : 0; - cycle.binderReplyCount += it.name == 'binder reply' ? it.count : 0; - cycle.binderTransactionAsyncCount += it.name == 'binder transaction async' ? it.count : 0; - } else { - thread.children.push(cycleItem); - } - } else { - process.children.push({ - title: it.thread + ' ' + '[' + it.tid + ']', - totalCount: it.count, - tid: it.tid, - pid: it.pid, - type: 'thread', - children: [cycleItem], - }) - } - } else { - group[`${it.pid}`] = { - title: it.process + ' ' + '[' + it.pid + ']', - totalCount: it.count, - tid: it.tid, - pid: it.pid, - type: 'process', - children: [ - { - title: it.thread + ' ' + '[' + it.tid + ']', - totalCount: it.count, - tid: it.tid, - pid: it.pid, - type: 'thread', - children: [cycleItem], - } - ] - } - } - }); - this.cacheBinderArr = JSON.parse(JSON.stringify(this.addCycleNumber(Object.values(group)))); - let groupArr = this.timeUnitConversion(Object.values(group)) - return groupArr; - } - - addCycleNumber(groupArr: Array): Array { - for (let i = 0; i < groupArr.length; i++) { - if (groupArr[i].type === 'cycle') { - groupArr[i].title = 'cycle ' + (i + 1) + '_' + groupArr[i].thread + ' ' + '[' + groupArr[i].tid + ']'; - groupArr[i].idx = i + 1; - } else { - this.addCycleNumber(groupArr[i].children!) - } - } - return groupArr - } - - timeUnitConversion(groupArr: Array): Array { - for (let i = 0; i < groupArr.length; i++) { - if (groupArr[i].type === 'cycle') { - groupArr[i].cycleDur = Number((groupArr[i].cycleDur / 1000000).toFixed(3)); - groupArr[i].cycleStartTime = Number((groupArr[i].cycleStartTime / 1000000).toFixed(3)); - } else { - this.timeUnitConversion(groupArr[i].children!) - } - } - return groupArr - } - - private theadClick(data: Array): void { - let labels = this.threadBindersTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - if (label.includes('Process') && i === 0) { - this.threadBindersTbl!.setStatus(data, false); - this.threadBindersTbl!.recycleDs = this.threadBindersTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Thread') && i === 1) { - for (let item of data) { - item.status = true; - if (item.children != undefined && item.children.length > 0) { - this.threadBindersTbl!.setStatus(item.children, false); - } - } - this.threadBindersTbl!.recycleDs = this.threadBindersTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Cycle') && i === 2) { - this.threadBindersTbl!.setStatus(data, true); - this.threadBindersTbl!.recycleDs = this.threadBindersTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); - } - }); - } - } - } - - binderWithCountList(rowCycleData: BinderGroup[]): Array { - let binderWithCountList: Array = []; - rowCycleData.forEach(it => { - if (it.totalCount !== 0) { - let cycleDataArr: BinderColumn[] = []; - if (it.binderTransactionCount !== 0) { - cycleDataArr.push({ - name: 'binder transaction', - count: it.binderTransactionCount!, - dur: it.cycleDur, - startNS: it.cycleStartTime, - idx: it.idx - }) - } - if (it.binderTransactionAsyncCount !== 0) { - cycleDataArr.push({ - name: 'binder transaction async', - count: it.binderTransactionAsyncCount!, - dur: it.cycleDur, - startNS: it.cycleStartTime, - idx: it.idx - }) - } - if (it.binderReplyCount !== 0) { - cycleDataArr.push({ - name: 'binder reply', - count: it.binderReplyCount!, - dur: it.cycleDur, - startNS: it.cycleStartTime, - idx: it.idx - }) - } - if (it.binderAsyncRcvCount !== 0) { - cycleDataArr.push({ - name: 'binder async rcv', - count: it.binderAsyncRcvCount!, - dur: it.cycleDur, - startNS: it.cycleStartTime, - idx: it.idx - }) - } - binderWithCountList.push(cycleDataArr) - } - }) - return binderWithCountList; - } - - findThreadByThreadId(groupArr: Array, threadId: number): BinderGroup[] { - let currentSelectThread: BinderGroup[] = []; - groupArr.forEach(p => { - p.children?.forEach(th => { - if (th.tid === threadId) { - currentSelectThread = th.children! - } - }) - }) - return currentSelectThread - } - - initElements(): void { - this.threadBindersTbl = this.shadowRoot?.querySelector('#tb-binder-count'); - this.chartTotal = this.shadowRoot!.querySelector('#chart_cycle'); - this.cycleAStartRangeDIV = this.shadowRoot?.querySelector('#cycle-a-start-range'); - this.cycleAEndRangeDIV = this.shadowRoot?.querySelector('#cycle-a-end-range'); - this.cycleBStartRangeDIV = this.shadowRoot?.querySelector('#cycle-b-start-range'); - this.cycleBEndRangeDIV = this.shadowRoot?.querySelector('#cycle-b-end-range'); - - this.threadStatesDIV = this.shadowRoot!.querySelector('#dataCut'); - this.threadStatesDIV?.children[2].children[0].addEventListener('click', (e) => { - this.dispalyQueryArea(true); - this.dataSource = []; - // @ts-ignore - this.dataSingleCut(this.threadStatesDIV!.children[0], this.threadStatesDIV?.children[1]); - }) - this.threadStatesDIV?.children[2].children[1].addEventListener('click', (e) => { - this.dispalyQueryArea(true); - this.dataSource = []; - // @ts-ignore - this.dataLoopCut(this.threadStatesDIV?.children[0], this.threadStatesDIV?.children[1]); - }) - - this.threadBindersTbl!.addEventListener('row-click', (evt: any) => { - let currentData = evt.detail.data; - if (currentData.type === 'thread') { - this.currentThreadId = currentData.tid + '' + currentData.pid; - this.clearCycleRange(); - currentData.isSelected = true; - this.threadBindersTbl!.clearAllSelection(currentData); - this.threadBindersTbl!.setCurrentSelection(currentData); - this.rowCycleData = currentData.children; - this.dispalyQueryArea(false); - let totalCount = currentData.totalCount; - this.dataSource = []; - this.dataSource.push({ - xName: 'Total', - yAverage: totalCount !== 0 ? Math.ceil(totalCount / this.rowCycleData!.length) : 0 - }) - if (this.dataSource!.length !== 0) { - this.drawColumn(); - } - let threaId = currentData.tid; - let rowThreadBinderArr = this.findThreadByThreadId(this.cacheBinderArr!, threaId); - let binderList = this.binderWithCountList(rowThreadBinderArr!); - // SegMenTaTion.setChartData('BINDER', binderList); - } - - if (currentData.type === 'cycle' && currentData.tid + '' + currentData.pid === this.currentThreadId) { - currentData.isSelected = true; - this.threadBindersTbl!.clearAllSelection(currentData); - this.threadBindersTbl!.setCurrentSelection(currentData); - // SegMenTaTion.tabHover('BINDER', true, currentData.idx); - } - }); - - this.shadowRoot?.querySelector('#query-btn')?.addEventListener('click', () => { - this.cycleARangeArr = this.rowCycleData?.filter((it: BinderGroup) => { - return it.cycleDur >= Number(this.cycleAStartRangeDIV!.value) - && it.cycleDur < Number(this.cycleAEndRangeDIV!.value); - }) - this.cycleBRangeArr = this.rowCycleData?.filter((it: BinderGroup) => { - return it.cycleDur >= Number(this.cycleBStartRangeDIV!.value) - && it.cycleDur < Number(this.cycleBEndRangeDIV!.value); - }) - let cycleACount = 0; - this.cycleARangeArr?.forEach((it: BinderGroup) => { - cycleACount += it.totalCount; - }) - let cycleBCount = 0; - this.cycleBRangeArr?.forEach((it: BinderGroup) => { - cycleBCount += it.totalCount; - }) - this.dataSource!.length > 1 && this.dataSource?.splice(1); - this.dataSource!.push({ - xName: 'cycleA', - yAverage: cycleACount !== 0 ? Math.ceil(cycleACount / this.cycleARangeArr!.length) : 0 - }) - this.dataSource!.push({ - xName: 'cycleB', - yAverage: cycleBCount !== 0 ? Math.ceil(cycleBCount / this.cycleBRangeArr!.length) : 0 - }) - if (this.dataSource!.length !== 0) { - this.drawColumn(); - } - }) - } - - clearCycleRange(): void { - this.cycleAStartRangeDIV!.value = ''; - this.cycleAEndRangeDIV!.value = ''; - this.cycleBStartRangeDIV!.value = ''; - this.cycleBEndRangeDIV!.value = ''; - } - - drawColumn(): void { - this.chartTotal!.dataSource = this.dataSource!; - this.chartTotal!.config = { - data: this.dataSource!, - appendPadding: 10, - xField: 'xName', - yField: 'yAverage', - seriesField: '', - removeUnit: true, - notSort: true, - color: (a) => { - if (a.xName === 'Total') { - return '#2f72f8'; - } else if (a.xName === 'cycleA') { - return '#ffab67'; - } else if (a.xName === 'cycleB') { - return '#a285d2'; - } else { - return '#0a59f7'; - } - }, - tip: (a) => { - if (a && a[0]) { - let tip = ''; - tip = `
    -
    Average: ${a[0].obj.yAverage}
    -
    `; - return tip; - } else { - return ''; - } - }, - label: null, - }; - } - - connectedCallback() { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.threadBindersTbl!); - } - - initHtml(): string { - return ` - -
    - - -
    - - -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - -
    - -
    -
    -
    - Cycle A: - - ~ - -
    -
    -
    - Cycle B: - - ~ - -
    -
    - -
    -
    -
    -
    -
    Average Binder Count
    - -
    -
    Total
    -
    CycleA
    -
    CycleB
    -
    -
    -
    -
    -
    - ` - } -} \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/binder/TabPaneThreadBinders.ts b/ide/src/trace/component/trace/sheet/binder/TabPaneThreadBinders.ts deleted file mode 100644 index d3a464198..000000000 --- a/ide/src/trace/component/trace/sheet/binder/TabPaneThreadBinders.ts +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../StackBar.js' -import { getTabBindersCount } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { BinderGroup } from '../../../../bean/BinderProcessThread.js'; - -@element('tabpane-thread-binder') -export class TabPaneThreadBinders extends BaseElement { - private threadBindersTbl: LitTable | null | undefined; - private currentSelectionParam: Selection | undefined; - - set data(threadStatesParam: SelectionParam | any) { - if (this.currentSelectionParam === threadStatesParam) { - return; - } - this.threadBindersTbl!.loading = true; - this.currentSelectionParam = threadStatesParam; - this.threadBindersTbl!.recycleDataSource = []; - let binderList: BinderGroup[] = []; - let threadIds = threadStatesParam.threadIds; - let processIds: any[] = [...new Set(threadStatesParam.processIds)]; - getTabBindersCount(processIds, threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs).then((result) => { - if (result != null && result.length > 0 && result[0].count != 0) { - binderList = result; - } - if (binderList.length > 0) { - this.timeUnitConversion(binderList); - this.threadBindersTbl!.recycleDataSource = this.transferToTreeData(binderList); - this.threadBindersTbl!.loading = false; - this.theadClick(this.threadBindersTbl!.recycleDataSource); - } else if (binderList.length === 0) { - this.threadBindersTbl!.recycleDataSource = []; - this.threadBindersTbl!.loading = false; - this.theadClick(this.threadBindersTbl!.recycleDataSource); - } - }) - } - - timeUnitConversion(binderList: Array) { - binderList.forEach(b => { - b.cycleDur = Number((b.cycleDur / 1000000).toFixed(3)); - b.cycleStartTime = Number((b.cycleStartTime / 1000000).toFixed(3)); - }) - } - - initElements(): void { - this.threadBindersTbl = this.shadowRoot?.querySelector('#tb-binder-count'); - this.threadBindersTbl!.itemTextHandleMap.set('title', Utils.transferBinderTitle); - } - - connectedCallback() { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.threadBindersTbl!); - } - - transferToTreeData(binderList: BinderGroup[]): BinderGroup[] { - let group: any = {}; - binderList.forEach((it: BinderGroup) => { - if (group[`${it.pid}`]) { - let process = group[`${it.pid}`]; - process.totalCount += it.count; - let thread = process.children.find((child: BinderGroup) => child.title === `T-${it.tid}`); - if (thread) { - thread.totalCount += it.count; - thread.binderTransactionCount += it.name == 'binder transaction' ? it.count : 0; - thread.binderAsyncRcvCount += it.name == 'binder async rcv' ? it.count : 0; - thread.binderReplyCount += it.name == 'binder reply' ? it.count : 0; - thread.binderTransactionAsyncCount += it.name == 'binder transaction async' ? it.count : 0; - } else { - process.children.push({ - title: `T-${it.tid}`, - totalCount: it.count, - binderTransactionCount: it.name == 'binder transaction' ? it.count : 0, - binderAsyncRcvCount: it.name == 'binder async rcv' ? it.count : 0, - binderReplyCount: it.name == 'binder reply' ? it.count : 0, - binderTransactionAsyncCount: it.name == 'binder transaction async' ? it.count : 0, - tid: it.tid, - pid: it.pid - }) - } - } else { - group[`${it.pid}`] = { - title: `P-${it.pid}`, - totalCount: it.count, - tid: it.tid, - pid: it.pid, - cycleDur: it.cycleDur || 0, - cycleStartTime: it.cycleStartTime, - children: [ - { - title: `T-${it.tid}`, - totalCount: it.count, - binderTransactionCount: it.name == 'binder transaction' ? it.count : 0, - binderAsyncRcvCount: it.name == 'binder async rcv' ? it.count : 0, - binderReplyCount: it.name == 'binder reply' ? it.count : 0, - binderTransactionAsyncCount: it.name == 'binder transaction async' ? it.count : 0, - tid: it.tid, - pid: it.pid, - } - ] - } - } - }); - return Object.values(group); - } - - private theadClick(data: Array) { - let labels = this.threadBindersTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - if (label.includes('Process') && i === 0) { - this.threadBindersTbl!.setStatus(data, false); - this.threadBindersTbl!.recycleDs = this.threadBindersTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Thread') && i === 1) { - for (let item of data) { - item.status = true; - if (item.children != undefined && item.children.length > 0) { - this.threadBindersTbl!.setStatus(item.children, false); - } - } - this.threadBindersTbl!.recycleDs = this.threadBindersTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } - }); - } - } - } - - - initHtml(): string { - return ` - - - - - - - - - - - - - - - - - ` - } -} \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts index 4f2accc53..69f4b271d 100644 --- a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts +++ b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts @@ -12,797 +12,224 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../StackBar.js' -import { getTabRunningPercent, queryCpuFreqUsageData, queryCpuFreqFilterId, querySearchFuncData } from '../../../../database/SqlLite.js'; +import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../StackBar.js'; +import { + getTabRunningPercent, + querySearchFuncData, + queryCpuFreqUsageData, + queryCpuFreqFilterId, +} from '../../../../database/SqlLite.js'; import { Utils } from '../../base/Utils.js'; import { resizeObserver } from '../SheetUtils.js'; import { SliceGroup } from '../../../../bean/StateProcessThread.js'; -import { LitChartScatter } from '../../../../../base-ui/chart/scatter/LitChartScatter.js'; -import { SegMenTaTion } from "../../../chart/SpSegmentationChart.js"; -import { TabPaneFreqUsageConfig, TabPaneRunningConfig, TabPaneCpuFreqConfig } from "./TabPaneFreqUsageConfig.js"; @element('tabpane-freqdatacut') export class TabPaneFreqDataCut extends BaseElement { - private threadStatesTbl: LitTable | null | undefined; - private threadStatesTblSource: Array = []; - private currentSelectionParam: SelectionParam | any; - private threadStatesDIV: HTMLDivElement | null | undefined; - private scatterInput: HTMLInputElement | null | undefined; - private initData: Map> = new Map(); - private processArr: Array = []; - private threadArr: Array = []; - private statisticsScatter: LitChartScatter | null | undefined; + private threadStatesTbl: LitTable | null | undefined; + private threadStatesTblSource: Array = []; + private currentSelectionParam: SelectionParam | any; + private threadStatesDIV: Element | null | undefined; + private initData: any = new Map(); + private processArr: any = new Array(); + private threadArr: any = new Array(); - set data(threadStatesParam: SelectionParam | any) { - if (this.currentSelectionParam === threadStatesParam) { - return; - } - this.currentSelectionParam = threadStatesParam; - this.initData = new Map(); - this.threadArr = []; - this.initUI(); - this.init(threadStatesParam); - let pidArr: Array = []; - // 整理进程级的数组信息 - let processArr: Array = threadStatesParam.processIds.length > 1 ? [...new Set(threadStatesParam.processIds)] : threadStatesParam.processIds; - for (let i of processArr) { - pidArr.push(new TabPaneFreqUsageConfig(Utils.PROCESS_MAP.get(i) === null ? 'Process ' + i : Utils.PROCESS_MAP.get(i) + ' ' + i, '', i, '', 0, '', '', 0, '', 0, 'process', -1, [])); - } - // 拷贝给私有属性,以便后续进行数据切割时免除整理进程层级数据 - this.processArr = pidArr; - } - /** - * 初始化数据 - */ - async init(threadStatesParam: SelectionParam | any): Promise { - let [runningData, sum]: Array = await this.queryRunningData(threadStatesParam); - let cpuFreqData: Array = await this.queryCpuFreqData(threadStatesParam); - if (runningData.size > 0) { - // 将cpu频点数据与running状态数据整合,保证其上该段时长内有对应的cpu频点数据 - this.mergeFreqData(runningData, cpuFreqData, sum); - this.threadStatesTbl!.loading = false; - } else { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - } - } - /** - * 重置UI输入框等组件为默认状态 - */ - initUI(): void { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = true; - let tableValue: any = this.threadStatesTbl; - tableValue.value = []; - let divRoot1: any = this.shadowRoot?.querySelector('#dataCutThreadId'); - divRoot1.value = ''; - divRoot1.style.border = '1px solid rgb(151,151,151)'; - let divRoot2: any = this.shadowRoot?.querySelector('#dataCutThreadFunc'); - divRoot2.value = ''; - divRoot2.style.border = '1px solid rgb(151,151,151)'; - let divRoot3: any = this.shadowRoot?.querySelector('#maxFreq'); - divRoot3.style.border = '1px solid rgb(151,151,151)'; - let divRoot4: any = this.shadowRoot?.querySelector('#maxHz'); - divRoot4.style.border = '1px solid rgb(151,151,151)'; - let divRoot5: any = this.shadowRoot?.querySelector('#cycle-a-start-range'); - divRoot5.value = '' - let divRoot6: any = this.shadowRoot?.querySelector('#cycle-a-end-range'); - divRoot6.value = ''; - let divRoot7: any = this.shadowRoot?.querySelector('#cycle-b-start-range'); - divRoot7.value = ''; - let divRoot8: any = this.shadowRoot?.querySelector('#cycle-b-end-range'); - divRoot8.value = ''; - // @ts-ignore - this.shadowRoot?.querySelector('#cycleQuery')!.style.display = 'none'; - // @ts-ignore - this.statisticsScatter!.config = undefined; + set data(threadStatesParam: SelectionParam | any) { + if (this.currentSelectionParam === threadStatesParam) { + return; } - /** - * 查询cpu频点信息 - */ - async queryCpuFreqData(threadStatesParam: SelectionParam | any): Promise> { + this.currentSelectionParam = threadStatesParam; + this.threadStatesTblSource = []; + this.threadStatesTbl!.recycleDataSource = []; + this.threadStatesTbl!.loading = true; + this.initData = new Map(); + let tableValue: any = this.threadStatesTbl; + tableValue.value = []; + let divRoot1: any = this.shadowRoot?.querySelector('#dataCutThreadId'); + divRoot1.value = ''; + let divRoot2: any = this.shadowRoot?.querySelector('#dataCutThreadFunc'); + divRoot2.value = ''; + // 查询running状态线程数据 + getTabRunningPercent(threadStatesParam.threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs).then( + (result) => { // 查询cpu及id信息 - let result: Array = await queryCpuFreqFilterId(); - // 以键值对形式将cpu及id进行对应,后续会将频点数据与其对应cpu进行整合 - let IdMap: Map = new Map(); - let queryId: Array = []; - for (let i = 0; i < result.length; i++) { - queryId.push(result[i].id); - IdMap.set(result[i].id, result[i].cpu); - } - let dealArr: Array = []; - // 通过id去查询频点数据 - let res: Array = await queryCpuFreqUsageData(queryId); - for (let i of res) { - let obj = new TabPaneCpuFreqConfig(i.startNS + threadStatesParam.recordStartNs, IdMap.get(i.filter_id)!, i.value, i.dur) - dealArr.push(obj); - } - return dealArr; - } - - /** - * 查询框选区域内的所有running状态数据 - */ - async queryRunningData(threadStatesParam: SelectionParam | any): Promise> { - let result: Array = await getTabRunningPercent(threadStatesParam.threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs); - let needDeal: Map> = new Map(), sum: number = 0; - if (result != null && result.length > 0) { - let processArr: Array = threadStatesParam.processIds.length > 1 ? [...new Set(threadStatesParam.processIds)] : threadStatesParam.processIds; - for (let e of result) { - if (processArr.includes(e.pid)) { - if (needDeal.get(e.pid + '_' + e.tid) === undefined) { - this.threadArr.push(new TabPaneFreqUsageConfig(Utils.THREAD_MAP.get(e.tid) + ' ' + e.tid, '', e.pid, e.tid, 0, '', '', 0, '', 0, 'thread', -1, [])); - needDeal.set(e.pid + '_' + e.tid, new Array()); - } - if ((e.ts < (threadStatesParam.leftNs + threadStatesParam.recordStartNs)) && ((e.ts + e.dur) > (threadStatesParam.leftNs + threadStatesParam.recordStartNs))) { - const ts = e.ts; - e.ts = threadStatesParam.leftNs + threadStatesParam.recordStartNs; - e.dur = ts + e.dur - (threadStatesParam.leftNs + threadStatesParam.recordStartNs); - } - if ((e.ts + e.dur) > (threadStatesParam.rightNs + threadStatesParam.recordStartNs)) { - e.dur = threadStatesParam.rightNs + threadStatesParam.recordStartNs - e.ts; - } - let process = Utils.PROCESS_MAP.get(e.pid); - let thread = Utils.THREAD_MAP.get(e.tid); - e.process = process == null || process.length == 0 ? '[NULL]' : process; - e.thread = thread == null || thread.length == 0 ? '[NULL]' : thread; - let arr: any = needDeal.get(e.pid + '_' + e.tid); - sum += e.dur; - arr.push(e); - } - } - } - return [needDeal, sum]; - } - - /** - * 将cpu频点数据与running状态数据整合,保证其上该段时长内有对应的cpu频点数据 - */ - mergeFreqData(needDeal: Map>, dealArr: Array, sum: number): void { - needDeal.forEach((value: Array, key: string) => { - let resultList: Array = []; - for (let i = 0; i < value.length; i++) { - for (let j = 0; j < dealArr.length; j++) { - // 只需要判断running状态数据与频点数据cpu相同的情况 - if (value[i].cpu === dealArr[j].cpu) { - // running状态数据的开始时间大于频点数据开始时间,小于频点结束时间。且running状态数据的持续时间小于频点结束时间减去running状态数据开始时间的情况 - if (value[i].ts > dealArr[j].startNS && value[i].ts < (dealArr[j].startNS + dealArr[j].dur) && value[i].dur < (dealArr[j].startNS + dealArr[j].dur - value[i].ts)) { - resultList.push(new TabPaneFreqUsageConfig(value[i].thread, value[i].ts, value[i].pid, value[i].tid, 0, value[i].cpu, dealArr[j].value, value[i].dur, '', value[i].dur / sum * 100, 'freqdata', -1, undefined)); - break; - } - // running状态数据的开始时间大于频点数据开始时间,小于频点结束时间。且running状态数据的持续时间大于频点结束时间减去running状态数据开始时间的情况 - if (value[i].ts > dealArr[j].startNS && value[i].ts < (dealArr[j].startNS + dealArr[j].dur) && value[i].dur > (dealArr[j].startNS + dealArr[j].dur - value[i].ts)) { - resultList.push(new TabPaneFreqUsageConfig(value[i].thread, value[i].ts, value[i].pid, value[i].tid, 0, value[i].cpu, dealArr[j].value, (dealArr[j].startNS + dealArr[j].dur - value[i].ts), '', (dealArr[j].startNS + dealArr[j].dur - value[i].ts) / sum * 100, 'freqdata', -1, undefined)); - } - // running状态数据的开始时间小于频点数据开始时间,running状态数据的结束时间大于频点数据开始时间。且running状态数据在频点数据开始时间后的持续时间小于频点数据持续时间的情况 - if (value[i].ts < dealArr[j].startNS && (value[i].ts + value[i].dur) > dealArr[j].startNS && (value[i].dur + value[i].ts - dealArr[j].startNS) < dealArr[j].dur) { - resultList.push(new TabPaneFreqUsageConfig(value[i].thread, dealArr[j].startNS, value[i].pid, value[i].tid, 0, value[i].cpu, dealArr[j].value, (value[i].dur + value[i].ts - dealArr[j].startNS), '', (value[i].dur + value[i].ts - dealArr[j].startNS) / sum * 100, 'freqdata', -1, undefined)); - break; - } - // running状态数据的开始时间小于频点数据开始时间,running状态数据的结束时间大于频点数据开始时间。且running状态数据在频点数据开始时间后的持续时间大于频点数据持续时间的情况 - if (value[i].ts < dealArr[j].startNS && (value[i].ts + value[i].dur) > dealArr[j].startNS && (value[i].dur + value[i].ts - dealArr[j].startNS) > dealArr[j].dur) { - resultList.push(new TabPaneFreqUsageConfig(value[i].thread, dealArr[j].startNS, value[i].pid, value[i].tid, 0, value[i].cpu, dealArr[j].value, dealArr[j].dur, '', dealArr[j].dur / sum * 100, 'freqdata', -1, undefined)); - } - // running状态数据的开始时间小于频点数据开始时间,running状态数据的持续时间小于频点数据开始时间的情况 - if (value[i].ts < dealArr[j].startNS && (value[i].ts + value[i].dur) < dealArr[j].startNS) { - resultList.push(new TabPaneFreqUsageConfig(value[i].thread, value[i].ts, value[i].pid, value[i].tid, 0, value[i].cpu, 'unknown', value[i].dur, '', value[i].dur / sum * 100, 'freqdata', -1, undefined)); - break; - } - } - } - } - this.initData.set(key, resultList); - }) - } - /** - * single方式切割数据功能 - */ - dataSingleCut(threadId: HTMLInputElement, threadFunc: HTMLInputElement, resultList: Map>): void { - threadId.style.border = '1px solid rgb(151,151,151)'; - threadFunc.style.border = '1px solid rgb(151,151,151)'; - let threadIdValue = threadId.value.trim(); - let threadFuncName = threadFunc.value.trim(); - let leftNS = this.currentSelectionParam.leftNs; - let rightNS = this.currentSelectionParam.rightNs; - let tableValue: any = this.threadStatesTbl; - tableValue.value = []; - if (threadIdValue != '' && threadFuncName != '') { - // 根据用户输入的线程ID,方法名去查询数据库,得到对应的方法起始时间,持续时间等数据,以便作为依据进行后续数据切割 - querySearchFuncData(threadFuncName, Number(threadIdValue), leftNS, rightNS).then(result => { - if (result != null && result.length > 0) { - // targetMap为全局initData的拷贝对象,dealArr数组用来存放周期切割依据数据 - let targetMap: Map> = new Map(), dealArr: Array = []; - // 新创建map对象接收传过来的实参map - resultList.forEach((item: Array, key: string) => { - targetMap.set(key, JSON.parse(JSON.stringify(item))); - }) - // 整理周期切割依据的数据 - for (let i of result) { - if (i.startTime + this.currentSelectionParam.recordStartNs + i.dur < this.currentSelectionParam.rightNs + this.currentSelectionParam.recordStartNs) { - dealArr.push({ 'ts': i.startTime + this.currentSelectionParam.recordStartNs, 'dur': i.dur }); - } - } - let cycleMap: Map> = new Map(), totalList: Map> = new Map(); - this.mergeSingleData(dealArr, targetMap, cycleMap, totalList); - // 拷贝线程数组,防止数据污染 - let threadArr = JSON.parse(JSON.stringify(this.threadArr)); - // 拷贝进程数组,防止数据污染 - let processArr = JSON.parse(JSON.stringify(this.processArr)); - // 将周期层级防止到线程层级下 - this.mergeThreadData(threadArr, cycleMap); - // 将原始数据放置到对应的线程层级下,周期数据前 - let totalData = this.merge(totalList); - this.mergeTotalData(threadArr, totalData); - // 合并数据到进程层级下 - this.mergePidData(processArr, threadArr); - this.fixedDeal(processArr); - this.threadStatesTblSource = processArr; - this.threadStatesTbl!.recycleDataSource = processArr; - this.threadStatesTbl!.loading = false; - this.threadClick(processArr); - } else { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - } - }) - } else { - this.threadStatesTbl!.loading = false; - if (threadIdValue == '') { - threadId.style.border = '2px solid rgb(255,0,0)'; - } - if (threadFuncName == '') { - threadFunc.style.border = '2px solid rgb(255,0,0)'; - } - } - } - /** - * 整合Single切割方式中的频点数据与方法周期数据 - */ - mergeSingleData(dealArr: Array, targetMap: Map>, cycleMap: Map>, totalList: Map>): void { - let timeDur = this.currentSelectionParam.recordStartNs; - targetMap.forEach((value, key) => { - cycleMap.set(key, new Array()); - totalList.set(key, new Array()); - for (let i = 0; i < dealArr.length; i++) { - let cpuArr: Array = [], resList: Array = [], cpuMap: Map> = new Map(); - // 时间倍数值 - const countMutiple = 1000000; - cpuMap.set(key, new Array()); - cycleMap.get(key)?.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[0].thread, ((dealArr[i].ts - timeDur) / 1000000).toFixed(3), key.split('_')[0], key.split('_')[1], 0, '', '', 0, (dealArr[i].dur / 1000000).toFixed(3), 0, 'cycle', i + 1, [])); - for (let j = 0; j < value.length; j++) { - // 判断若用户导入json文件,则替换为对应cpu下的对应频点的算力值进行算力消耗计算 - let consumptionMap: Map = SegMenTaTion.freqInfoMapData.size > 0 && SegMenTaTion.freqInfoMapData.get(value[j].cpu); - // 若存在算力值,则直接取值做计算。若不存在算力值,且频点值不为unknown的情况,则取频点值做计算,若为unknown,则取0做兼容 - const consumption = (consumptionMap && consumptionMap.get(value[j].freq)) ? consumptionMap.get(value[j].freq) : (value[j].freq == 'unknown' ? 0 : value[j].freq); - if (!cpuArr.includes(value[j].cpu)) { - cpuArr.push(value[j].cpu); - cpuMap.get(key)?.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[j].thread, '', value[j].pid, value[j].tid, 0, value[j].cpu, '', 0, '', 0, 'cpu', -1, [])); - } - // 以下为频点数据按Single周期切割数据如何取舍的判断条件,dealArr为周期切割依据,value为某一线程下的频点汇总数据 - // 如果频点数据开始时间大于某一周期起始时间,小于该周期的结束时间。且频点数据结束时间小于周期结束时间的情况 - if (dealArr[i].ts < value[j].ts && dealArr[i].ts + dealArr[i].dur > value[j].ts && dealArr[i].ts + dealArr[i].dur > value[j].ts + value[j].dur) { - resList.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[j].thread, '', value[j].pid, value[j].tid, (consumption * value[j].dur) / countMutiple, value[j].cpu, value[j].freq, value[j].dur, '', value[j].percent, 'freqdata', i, undefined)); - totalList.get(key)?.push(new TabPaneFreqUsageConfig(value[j].thread, '', value[j].pid, value[j].tid, (consumption * value[j].dur) / countMutiple, value[j].cpu, value[j].freq, value[j].dur, '', value[j].percent, 'freqdata', i, undefined)); - } - // 如果频点数据开始时间大于某一周期起始时间,小于该周期的结束时间。且频点数据结束时间大于等于周期结束时间的情况 - if (dealArr[i].ts < value[j].ts && dealArr[i].ts + dealArr[i].dur > value[j].ts && dealArr[i].ts + dealArr[i].dur <= value[j].ts + value[j].dur) { - resList.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[j].thread, '', value[j].pid, value[j].tid, (dealArr[i].ts + dealArr[i].dur - value[j].ts) * consumption / countMutiple, value[j].cpu, value[j].freq, dealArr[i].ts + dealArr[i].dur - value[j].ts, '', (dealArr[i].ts + dealArr[i].dur - value[j].ts) / value[j].dur * value[j].percent, 'freqdata', i, undefined)); - totalList.get(key)?.push(new TabPaneFreqUsageConfig(value[j].thread, '', value[j].pid, value[j].tid, (dealArr[i].ts + dealArr[i].dur - value[j].ts) * consumption / countMutiple, value[j].cpu, value[j].freq, dealArr[i].ts + dealArr[i].dur - value[j].ts, '', (dealArr[i].ts + dealArr[i].dur - value[j].ts) / value[j].dur * value[j].percent, 'freqdata', i, undefined)); - break; - } - // 如果频点数据开始时间小于某一周期起始时间,结束时间大于该周期的开始时间。且频点数据结束时间大于周期结束时间的情况 - if (dealArr[i].ts > value[j].ts && value[j].ts + value[j].dur > dealArr[i].ts && value[j].ts + value[j].dur > dealArr[i].ts + dealArr[i].dur) { - resList.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[j].thread, '', value[j].pid, value[j].tid, dealArr[i].dur * consumption / countMutiple, value[j].cpu, value[j].freq, dealArr[i].dur, '', dealArr[i].dur / value[j].dur * value[j].percent, 'freqdata', i, undefined)); - totalList.get(key)?.push(new TabPaneFreqUsageConfig(value[j].thread, '', value[j].pid, value[j].tid, dealArr[i].dur * consumption / countMutiple, value[j].cpu, value[j].freq, dealArr[i].dur, '', dealArr[i].dur / value[j].dur * value[j].percent, 'freqdata', i, undefined)); - break; - } - // 如果频点数据开始时间小于某一周期起始时间,结束时间大于该周期的开始时间。且频点数据结束时间小于等于周期结束时间的情况 - if (dealArr[i].ts > value[j].ts && value[j].ts + value[j].dur > dealArr[i].ts && value[j].ts + value[j].dur <= dealArr[i].ts + dealArr[i].dur) { - resList.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[j].thread, '', value[j].pid, value[j].tid, (value[j].ts + value[j].dur - dealArr[i].ts) * consumption / countMutiple, value[j].cpu, value[j].freq, value[j].ts + value[j].dur - dealArr[i].ts, '', (value[j].ts + value[j].dur - dealArr[i].ts) / value[j].dur * value[j].percent, 'freqdata', i, undefined)); - totalList.get(key)?.push(new TabPaneFreqUsageConfig(value[j].thread, '', value[j].pid, value[j].tid, (value[j].ts + value[j].dur - dealArr[i].ts) * consumption / countMutiple, value[j].cpu, value[j].freq, value[j].ts + value[j].dur - dealArr[i].ts, '', (value[j].ts + value[j].dur - dealArr[i].ts) / value[j].dur * value[j].percent, 'freqdata', i, undefined)); - } - } - this.mergeData(resList); - // 整理排序相同周期下的数据 - this.mergeCpuData(cpuMap.get(key)!, resList); - // 将cpu数据放置到对应周期层级下 - this.mergeCycleData(cycleMap.get(key)![i], cpuMap.get(key)); - } - }); - } - /** - * Loop方式切割数据功能 - */ - dataLoopCut(threadId: HTMLInputElement, threadFunc: HTMLInputElement, resultList: Map>): void { - threadId.style.border = '1px solid rgb(151,151,151)'; - threadFunc.style.border = '1px solid rgb(151,151,151)'; - let threadIdValue = threadId!.value.trim(); - let threadFuncName = threadFunc.value.trim(); - let leftNS = this.currentSelectionParam.leftNs; - let rightNS = this.currentSelectionParam.rightNs; - let tableValue: any = this.threadStatesTbl; - tableValue.value = []; - if (threadIdValue !== '' && threadFuncName !== '') { - querySearchFuncData(threadFuncName, Number(threadIdValue), leftNS, rightNS).then(res => { - if (res !== null && res.length > 0) { - // targetMap为全局initData的拷贝对象,cutArr数组用来存放周期切割依据数据 - let targetMap: Map> = new Map(), cutArr: Array = []; - // 新创建map对象接收传过来的实参map - resultList.forEach((item: Array, key: string) => { - targetMap.set(key, JSON.parse(JSON.stringify(item))); - }) - // 根据线程id及方法名获取的数据,处理后用作切割时间依据,时间跨度为整个方法开始时间到末个方法开始时间 - for (let i of res) { - cutArr[cutArr.length - 1] && (cutArr[cutArr.length - 1].dur = i.startTime ? i.startTime + this.currentSelectionParam.recordStartNs - cutArr[cutArr.length - 1].ts : 0); - cutArr.push({ 'ts': i.startTime + this.currentSelectionParam.recordStartNs }); - } - let cycleMap: Map> = new Map(); - let totalList: Map> = new Map(); - this.mergeLoopData(cutArr, targetMap, cycleMap, totalList); - let threadArr: Array = JSON.parse(JSON.stringify(this.threadArr)); - let processArr: Array = JSON.parse(JSON.stringify(this.processArr)); - this.mergeThreadData(threadArr, cycleMap); - let totalData = this.merge(totalList); - this.mergeTotalData(threadArr, totalData); - this.mergePidData(processArr, threadArr); - this.fixedDeal(processArr); - this.threadStatesTblSource = processArr; - this.threadStatesTbl!.recycleDataSource = processArr; - this.threadStatesTbl!.loading = false; - this.threadClick(processArr); - } else { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - } - }) - } else { - this.threadStatesTbl!.loading = false; - if (threadIdValue === '') { - threadId.style.border = '2px solid rgb(255,0,0)'; - } - if (threadFuncName === '') { - threadFunc.style.border = '2px solid rgb(255,0,0)'; - } - } - } - /** - * 整合Loop切割方式中的频点数据与方法周期数据 - */ - mergeLoopData(cutArr: Array, targetMap: Map>, cycleMap: Map>, totalList: Map>): void { - let timeDur: number = this.currentSelectionParam.recordStartNs; - targetMap.forEach((value, key) => { - cycleMap.set(key, new Array()); - totalList.set(key, new Array()); - for (let i = 0; i < cutArr.length - 1; i++) { - let cpuArr: Array = [], resList: Array = [], cpuMap: Map> = new Map(); - // 时间倍数值 - const countMutiple = 1000000; - cpuMap.set(key, new Array()); - // 创建周期层级数据 - cycleMap.get(key)?.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[0].thread, ((cutArr[i].ts - timeDur) / 1000000).toFixed(3), key.split('_')[0], key.split('_')[1], 0, '', '', 0, (cutArr[i].dur / 1000000).toFixed(3), 0, 'cycle', i + 1, [])); - for (let j = 0; j < value.length; j++) { - // 判断若用户导入json文件,则替换为对应cpu下的对应频点的算力值进行算力消耗计算 - let consumptionMap: Map = SegMenTaTion.freqInfoMapData.size > 0 && SegMenTaTion.freqInfoMapData.get(value[j].cpu); - // 若存在算力值,则直接取值做计算。若不存在算力值,且频点值不为unknown的情况,则取频点值做计算,若为unknown,则取0做兼容 - const consumption = (consumptionMap && consumptionMap.get(value[j].freq)) ? consumptionMap.get(value[j].freq) : (value[j].freq == 'unknown' ? 0 : value[j].freq); - if (!cpuArr.includes(value[j].cpu)) { - cpuArr.push(value[j].cpu); - // 创建cpu层级数据,以便后续生成树结构 - cpuMap.get(key)?.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[j].thread, '', value[j].pid, value[j].tid, 0, value[j].cpu, '', 0, '', 0, 'cpu', -1, [])); - } - // 以下为频点数据按Loop周期切割数据如何取舍的判断条件,cutArr为周期切割依据,value为某一线程下的频点汇总数据 - // 如果频点数据开始时间大于某一周期起始时间,且结束时间小于等于下一同名方法开始时间的情况 - if (value[j].ts >= cutArr[i].ts && (value[j].ts + value[j].dur) <= cutArr[i + 1].ts) { - resList.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[j].thread, '', value[j].pid, value[j].tid, (consumption * value[j].dur) / countMutiple, value[j].cpu, value[j].freq, value[j].dur, '', value[j].percent, 'freqdata', i, undefined)); - totalList.get(key)?.push(new TabPaneFreqUsageConfig(value[j].thread, '', value[j].pid, value[j].tid, (consumption * value[j].dur) / countMutiple, value[j].cpu, value[j].freq, value[j].dur, '', value[j].percent, 'freqdata', i, undefined)); - } - // 如果频点数据开始时间大于某一周期起始时间,且结束时间大于下一同名方法开始时间的情况 - if (value[j].ts >= cutArr[i].ts && (value[j].ts + value[j].dur) > cutArr[i + 1].ts) { - if (cutArr[i + 1].ts - value[j].ts > 0) { - resList.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[j].thread, '', value[j].pid, value[j].tid, (consumption * (cutArr[i + 1].ts - value[j].ts)) / countMutiple, value[j].cpu, value[j].freq, cutArr[i + 1].ts - value[j].ts, '', value[j].percent * ((cutArr[i + 1].ts - value[j].ts) / value[j].dur), 'freqdata', i, undefined)); - totalList.get(key)?.push(new TabPaneFreqUsageConfig(value[j].thread, '', value[j].pid, value[j].tid, (consumption * (cutArr[i + 1].ts - value[j].ts)) / countMutiple, value[j].cpu, value[j].freq, cutArr[i + 1].ts - value[j].ts, '', value[j].percent * ((cutArr[i + 1].ts - value[j].ts) / value[j].dur), 'freqdata', i, undefined)); - break; - } - } - // 如果频点数据开始时间小于某一周期起始时间,且结束时间大于下一同名方法开始时间的情况 - if (value[j].ts < cutArr[i].ts && (value[j].ts + value[j].dur) > cutArr[i + 1].ts) { - resList.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[j].thread, '', value[j].pid, value[j].tid, (consumption * (cutArr[i + 1].ts - cutArr[i].ts)) / countMutiple, value[j].cpu, value[j].freq, cutArr[i + 1].ts - cutArr[i].ts, '', value[j].percent * ((cutArr[i + 1].ts - cutArr[i].ts) / value[j].dur), 'freqdata', i, undefined)); - totalList.get(key)?.push(new TabPaneFreqUsageConfig(value[j].thread, '', value[j].pid, value[j].tid, (consumption * (cutArr[i + 1].ts - cutArr[i].ts)) / countMutiple, value[j].cpu, value[j].freq, cutArr[i + 1].ts - cutArr[i].ts, '', value[j].percent * ((cutArr[i + 1].ts - cutArr[i].ts) / value[j].dur), 'freqdata', i, undefined)); - } - // 如果频点数据开始时间小于某一周期起始时间,结束时间大于该方法开始时间。且频点数据结束时间小于下一同名方法开始时间 - if (value[j].ts < cutArr[i].ts && (value[j].ts + value[j].dur) > cutArr[i].ts && (value[j].ts + value[j].dur) < cutArr[i + 1].ts) { - resList.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[j].thread, '', value[j].pid, value[j].tid, (consumption * (value[j].dur + value[j].ts - cutArr[i].ts)) / countMutiple, value[j].cpu, value[j].freq, value[j].dur + value[j].ts - cutArr[i].ts, '', value[j].percent * ((value[j].dur + value[j].ts - cutArr[i].ts) / value[j].dur), 'freqdata', i, undefined)); - totalList.get(key)?.push(new TabPaneFreqUsageConfig(value[j].thread, '', value[j].pid, value[j].tid, (consumption * (value[j].dur + value[j].ts - cutArr[i].ts)) / countMutiple, value[j].cpu, value[j].freq, value[j].dur + value[j].ts - cutArr[i].ts, '', value[j].percent * ((value[j].dur + value[j].ts - cutArr[i].ts) / value[j].dur), 'freqdata', i, undefined)); - } + queryCpuFreqFilterId().then((r) => { + // 以键值对形式将cpu及id进行对应,后续会将频点数据与其对应cpu进行整合 + let IdMap = new Map(); + let queryId = new Array(); + for (let i = 0; i < r.length; i++) { + queryId.push(r[i].id); + IdMap.set(r[i].id, r[i].cpu); + } + // 通过id去查询频点数据 + queryCpuFreqUsageData(queryId).then((res) => { + if (result != null && result.length > 0) { + let sum = 0; + let dealArr = new Array(); + for (let i of res) { + dealArr.push({ + startNS: i.startNS + threadStatesParam.recordStartNs, + dur: i.dur, + value: i.value, + cpu: IdMap.get(i.filter_id), + }); + } + let needDeal = new Map(); + let pidArr = new Array(); + let threadArr = new Array(); + // 整理进程级的数组信息 + let processArr: any = + threadStatesParam.processIds.length > 1 + ? [...new Set(threadStatesParam.processIds)] + : threadStatesParam.processIds; + for (let i of processArr) { + pidArr.push({ + process: Utils.PROCESS_MAP.get(i) == null ? 'Process ' + i : Utils.PROCESS_MAP.get(i) + ' ' + i, + thread: Utils.PROCESS_MAP.get(i) == null ? 'Process ' + i : Utils.PROCESS_MAP.get(i) + ' ' + i, + pid: i, + tid: '', + count: 0, + cpu: '', + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); + } + // 拷贝给私有属性,以便后续进行数据切割时免除整理进程层级数据 + this.processArr = JSON.parse(JSON.stringify(pidArr)); + for (let e of result) { + if (processArr.includes(e.pid) && e.state == 'Running') { + if (needDeal.get(e.pid + '_' + e.tid) == undefined) { + threadArr.push({ + process: + Utils.PROCESS_MAP.get(e.pid) == null + ? 'Process ' + e.pid + : Utils.PROCESS_MAP.get(e.pid) + ' ' + e.pid, + thread: Utils.THREAD_MAP.get(e.tid) + ' ' + e.tid, + pid: e.pid, + tid: e.tid, + count: 0, + cpu: '', + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); + needDeal.set(e.pid + '_' + e.tid, new Array()); + } + if ( + e.ts < threadStatesParam.leftNs + threadStatesParam.recordStartNs && + e.ts + e.dur > threadStatesParam.leftNs + threadStatesParam.recordStartNs + ) { + const ts = e.ts; + e.ts = threadStatesParam.leftNs + threadStatesParam.recordStartNs; + e.dur = ts + e.dur - (threadStatesParam.leftNs + threadStatesParam.recordStartNs); + } + if (e.ts + e.dur > threadStatesParam.rightNs + threadStatesParam.recordStartNs) { + e.dur = threadStatesParam.rightNs + threadStatesParam.recordStartNs - e.ts; + } + let arr = needDeal.get(e.pid + '_' + e.tid); + let process = Utils.PROCESS_MAP.get(e.pid); + let thread = Utils.THREAD_MAP.get(e.tid); + e.process = process == null || process.length == 0 ? '[NULL]' : process; + e.thread = thread == null || thread.length == 0 ? '[NULL]' : thread; + e.stateJX = e.state; + e.state = Utils.getEndState(e.stateJX); + sum += e.dur; + arr.push(e); } - // 合并相同周期内的数据 - this.mergeData(resList); - // 整理排序相同周期下的数据 - this.mergeCpuData(cpuMap.get(key)!, resList); - // 将cpu数据放置到对应周期层级下 - this.mergeCycleData(cycleMap.get(key)![i], cpuMap.get(key)); + } + // 拷贝给私有属性,以便后续进行数据切割时免除整理线程层级数据 + this.threadArr = JSON.parse(JSON.stringify(threadArr)); + // 整理running线程数据、cpu层级信息 + this.mergeFreqData(needDeal, dealArr, sum); + this.threadStatesTbl!.loading = false; + } else { + this.threadStatesTblSource = []; + this.threadStatesTbl!.recycleDataSource = []; + this.threadStatesTbl!.loading = false; } + }); }); - } - /** - * 切割后整合好的周期频点数据放置到对应的线程下 - */ - mergeThreadData(threadArr: Array, cycleMap: Map>): void { - for (let i = 0; i < threadArr.length; i++) { - let cycleMapData = cycleMap.get(threadArr[i].pid + '_' + threadArr[i].tid); - for (let j = 0; j < cycleMapData!.length; j++) { - threadArr[i].children.push(cycleMapData![j]); - threadArr[i].count += cycleMapData![j].count; - threadArr[i].dur += cycleMapData![j].dur; - threadArr[i].percent += cycleMapData![j].percent; + } + ); + } + private threadClick(data: Array) { + let labels = this.threadStatesTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); + if (labels) { + for (let i = 0; i < labels.length; i++) { + let label = labels[i].innerHTML; + labels[i].addEventListener('click', (e) => { + if (label.includes('Process') && i === 0) { + this.threadStatesTbl!.setStatus(data, false); + this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); + } else if (label.includes('Thread') && i === 1) { + for (let item of data) { + item.status = true; + if (item.children != undefined && item.children.length > 0) { + this.threadStatesTbl!.setStatus(item.children, false); + } } - } - } - /** - * 切割后整合好的线程级频点数据放置到对应的进程 - */ - mergePidData(pidArr: Array, threadArr: Array): void { - for (let i = 0; i < pidArr.length; i++) { - for (let j = 0; j < threadArr.length; j++) { - if (pidArr[i].pid === threadArr[j].pid) { - pidArr[i].children.push(threadArr[j]); - pidArr[i].count += threadArr[j].count; - pidArr[i].dur += threadArr[j].dur; - pidArr[i].percent += threadArr[j].percent; - } - } - } - } - /** - * 合并相同周期内运行所在cpu相同、频点相同的数据 - */ - mergeData(resList: Array): void { - // 合并相同周期内的数据 - for (let i = 0; i < resList.length; i++) { - for (let j = i + 1; j < resList.length; j++) { - if (resList[i].cpu === resList[j].cpu && resList[i].freq === resList[j].freq && resList[i].id === resList[j].id) { - resList[i].dur += resList[j].dur; - resList[i].percent += resList[j].percent; - resList[i].count += resList[j].count; - resList.splice(j, 1); - j--; - } - } - } - } - /** - * 将cpu层级数据放到对应的周期层级下 - */ - mergeCycleData(obj: TabPaneFreqUsageConfig, arr: Array | undefined): void { - for (let i = 0; i < arr!.length; i++) { - if (arr![i].count === 0 && arr![i].dur === 0) { - continue; - } - obj.children?.push(arr![i]); - obj.count += arr![i].count; - obj.dur += arr![i].dur; - obj.percent += arr![i].percent; - } - } - /** - * 将切割好的不区分周期的数据作为total数据放到对应的线程层级下,周期数据前 - */ - mergeTotalData(threadArr: Array, totalData: Array): void { - for (let i = 0; i < threadArr.length; i++) { - for (let j = 0; j < totalData.length; j++) { - if (Number(threadArr[i].pid) === Number(totalData[j].pid) && Number(threadArr[i].tid) === Number(totalData[j].tid)) { - totalData[j].thread = 'TotalData'; - threadArr[i].children.unshift(totalData[j]); - } - } - } - } - /** - * 整理排序相同周期下的数据 - */ - mergeCpuData(cpuArray: Array, resList: Array): void { - // 以算力消耗降序排列 - resList.sort((a, b) => b.count - a.count); - // 以cpu升序排列 - cpuArray.sort((a: any, b: any) => a.cpu - b.cpu); - cpuArray.forEach((item: any) => { - for (let s = 0; s < resList.length; s++) { - if (item.cpu === resList[s].cpu) { - item.children.push(resList[s]); - item.count += resList[s].count; - item.dur += resList[s].dur; - item.percent += resList[s].percent; + this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); + } else if (label.includes('Cycle') && i === 2) { + for (let item of data) { + item.status = true; + for (let value of item.children ? item.children : []) { + value.status = true; + if (value.children != undefined && value.children.length > 0) { + this.threadStatesTbl!.setStatus(value.children, false); } + } } + this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); + } else if (label.includes('CPU') && i === 3) { + this.threadStatesTbl!.setStatus(data, true); + this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); + } }); - + } } - /** - * 切割好的不区分周期的数据,以相同cpu相同频点的进行整合 - */ - merge(totalList: Map>): Array { - let result: Array = new Array(); - totalList.forEach((value: any, key: any) => { - let countNum = result.push(new TabPaneFreqUsageConfig('', '', key.split('_')[0], key.split('_')[1], 0, '', '', 0, '', 0, 'cycle', 0, [])); - let cpuArr: Array = []; - let flagArr: Array = []; - for (let i = 0; i < value.length; i++) { - if (!flagArr.includes(value[i].cpu)) { - flagArr.push(value[i].cpu); - let flag = cpuArr.push(new TabPaneFreqUsageConfig(value[i].thread, '', value[i].pid, value[i].tid, 0, value[i].cpu, '', 0, '', 0, 'cpu', -1, [])); - result[countNum - 1].children?.push(cpuArr[flag - 1]); - } - for (let j = i + 1; j < value.length; j++) { - if (value[i].cpu === value[j].cpu && value[i].freq === value[j].freq) { - value[i].dur += value[j].dur; - value[i].percent += value[j].percent; - value[i].count += value[j].count; - value.splice(j, 1); - j--; - } - } - } - result[countNum - 1].children?.sort((a: any, b: any) => a.cpu - b.cpu); - for (let i = 0; i < cpuArr.length; i++) { - for (let j = 0; j < value.length; j++) { - if (cpuArr[i].cpu === value[j].cpu) { - cpuArr[i].children.push(value[j]); - cpuArr[i].dur += value[j].dur; - cpuArr[i].count += value[j].count; - cpuArr[i].percent += value[j].percent; - } - } - result[countNum - 1].dur += cpuArr[i].dur; - result[countNum - 1].count += cpuArr[i].count; - result[countNum - 1].percent += cpuArr[i].percent; - } + let scatterData: any = this.threadStatesTbl?.shadowRoot?.querySelectorAll('.tree-first-body'); + if (scatterData) { + for (let j = 0; j < scatterData.length; j++) { + let scatter = scatterData[j].data; + scatterData[j].addEventListener('click', (e: any) => { + console.log(scatter); }); - return result; - } - /** - * 递归整理数据,取小数位数,转换单位 - */ - fixedDeal(arr: Array): void { - if (arr === undefined) { - return; - } - for (let i = 0; i < arr.length; i++) { - arr[i].percent = arr[i].percent > 100 ? 100 : arr[i].percent; - arr[i].percent = arr[i].percent.toFixed(2); - arr[i].dur = (arr[i].dur / 1000000).toFixed(3); - if (arr[i].freq !== '') { - if (arr[i].freq === 'unknown') { - arr[i].freq = 'unknown'; - } else { - arr[i].freq = arr[i].freq / 1000; - } - } - if (!(SegMenTaTion.freqInfoMapData.size > 0)) { - arr[i].count = (arr[i].count / 1000).toFixed(3); - } else { - arr[i].count = (arr[i].count).toFixed(3); - } - this.fixedDeal(arr[i].children); - } + } } + } - /** - * 绑定表格点击事件 - */ - private threadClick(data: Array): void { - let labels = this.threadStatesTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - if (!this.threadStatesTblSource.length && !this.threadStatesTbl!.recycleDataSource.length) { - data = []; - } - if (label.includes('Process') && i === 0) { - this.threadStatesTbl!.setStatus(data, false); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Thread') && i === 1) { - for (let item of data) { - item.status = true; - if (item.children != undefined && item.children.length > 0) { - this.threadStatesTbl!.setStatus(item.children, false); - } - } - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Cycle') && i === 2) { - for (let item of data) { - item.status = true; - for (let value of item.children ? item.children : []) { - value.status = true; - if (value.children != undefined && value.children.length > 0) { - this.threadStatesTbl!.setStatus(value.children, false); - } - } - } - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('CPU') && i === 3) { - this.threadStatesTbl!.setStatus(data, true); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); - } - }); - } - } - } - /** - * 散点图渲染数据整理 - */ - render(res: Array, str: string, queryCycleScatter: Array): void { - let maxFreq: HTMLInputElement = this.scatterInput!.querySelector('#maxFreq')!; - let maxHz: HTMLInputElement = this.scatterInput!.querySelector('#maxHz')!; - maxFreq.style.border = '1px solid rgb(151,151,151)'; - maxHz.style.border = '1px solid rgb(151,151,151)'; - if (maxFreq.value && maxHz.value) { - if (/^[0-9]*$/.test(maxFreq.value) && /^[0-9]*$/.test(maxHz.value)) { - // @ts-ignore - this.shadowRoot?.querySelector('#cycleQuery')!.style.display = 'block'; - let freq: Map = (SegMenTaTion.freqInfoMapData.size > 0 && SegMenTaTion.freqInfoMapData.get(SegMenTaTion.freqInfoMapData.size - 1)); - // @ts-ignore - let yAxis: number = (freq && freq.get(Number(maxFreq.value) * 1000)) ? freq.get(Number(maxFreq.value) * 1000) : Number(maxFreq.value); - let xAxis: number = yAxis * 1000 / Number(maxHz.value);//MHz·s - // 需要做筛选时,会利用下面的cycleA、cycleB数组 - let scatterArr: Array> = [], traceRowdata: Array = [], cycleA: Array> = [], cycleB: Array> = []; - let cycleAStart: number = queryCycleScatter[0] || 0, cycleAEnd: number = queryCycleScatter[1] || 0, cycleBStart: number = queryCycleScatter[2] || 0, cycleBEnd: number = queryCycleScatter[3] || 0; - for (let i = 1; i < res.length; i++) { - const count: number = Number(res[i].count), dur: number = Number(res[i].cdur), r_dur: number = Number(res[i].dur);//MHz·ms ms ms - scatterArr.push([count, count / dur, i, dur, r_dur]); - traceRowdata.push( - { - 'dur': dur * 1000000, - 'value': count, - 'freq': Math.round(count / dur) * 1000, - 'startNS': Number(res[i].ts) * 1000000, - 'cycle': i - 1 - } - ); - if (dur >= cycleAStart && dur < cycleAEnd) { - cycleA.push([count, count / dur, i, dur, r_dur]); - } - if (dur >= cycleBStart && dur < cycleBEnd) { - cycleB.push([count, count / dur, i, dur, r_dur]); - } - } - this.setConfig(Number(maxHz.value), str, scatterArr, yAxis, xAxis, cycleA, cycleB); - SegMenTaTion.setChartData('CPU-FREQ', traceRowdata); - } else { - if (!/^[0-9]*$/.test(maxFreq.value)) { - maxFreq.style.border = '2px solid rgb(255,0,0)'; - } - if (!/^[0-9]*$/.test(maxHz.value)) { - maxHz.style.border = '2px solid rgb(255,0,0)'; - } - } - } else { - if (maxFreq.value === '') { - maxFreq.style.border = '2px solid rgb(255,0,0)'; - maxFreq.setAttribute('placeholder', 'Please input maxFreq'); - } - if (maxHz.value === '') { - maxHz.style.border = '2px solid rgb(255,0,0)'; - maxHz.setAttribute('placeholder', 'Please input Fps'); - } - SegMenTaTion.setChartData('CPU-FREQ', []); - } - } - - /** - * 配置散点图 - */ - setConfig(maxHz: number, str: string, scatterArr: Array>, yAxis: number, xAxis: number, cycleA: Array>, cycleB: Array>): void { - this.statisticsScatter!.config = { - // 纵轴坐标值 - yAxisLabel: [Math.round(yAxis / 5), Math.round(yAxis * 2 / 5), Math.round(yAxis * 3 / 5), Math.round(yAxis * 4 / 5), Math.round(yAxis)], - // 横轴坐标值 - xAxisLabel: [Math.round(xAxis / 5), Math.round(xAxis * 2 / 5), Math.round(xAxis * 3 / 5), Math.round(xAxis * 4 / 5), Math.round(xAxis), Math.round(xAxis * 6 / 5)], - // 横轴字段、纵轴字段 - AxisLabel: ['负载', '算力供给'], - // 是否加载最大负载线及均衡线 - drawload: true, - // 最大负载线及均衡线值 - load: [xAxis, maxHz], - // 绘制点数据信息存储数组 - paintingData: [], - // 当前移入点坐标信息 - hoverData: {}, - // 颜色池 - colorPool: () => ['#2f72f8', '#ffab67', '#a285d2'], - // 移入数据点时是否触发函数 - //@ts-ignore - hoverEvent: SegMenTaTion.tabHover, - // 渐变色背景信息 - globalGradient: undefined, - // 渲染数据点 - data: [scatterArr, cycleA, cycleB], - // 散点图title - title: str, - colorPoolText: () => ['Total', 'CycleA', 'CycleB'], - tip: (data: any) => { - return ` -
    - Cycle: ${data.c[2]};
    - Comsumption: ${data.c[0]};
    - Cycle_dur: ${data.c[3]} ms;
    - Running_dur: ${data.c[4]} ms;
    -
    - ` - } - }; - - } - - initElements(): void { - this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-running-datacut'); - // 绑定single、loop按钮点击事件 - this.threadStatesDIV = this.shadowRoot?.querySelector('#dataCut'); - this.threadStatesDIV?.children[2].children[0].addEventListener('click', (e) => { - this.threadStatesTbl!.loading = true; - // @ts-ignore - this.dataSingleCut(this.threadStatesDIV?.children[0]!, this.threadStatesDIV?.children[1]!, this.initData); - }) - this.threadStatesDIV?.children[2].children[1].addEventListener('click', (e) => { - this.threadStatesTbl!.loading = true; - // @ts-ignore - this.dataLoopCut(this.threadStatesDIV?.children[0]!, this.threadStatesDIV?.children[1]!, this.initData); - }) - this.statisticsScatter = this.shadowRoot?.querySelector('#chart-scatter'); - // 增加表格thread层级点击更新散点图事件、周期层级点击高亮泳道图对应段事件 - let scatterData: Array = new Array(); - let str: string = ''; - this.threadStatesTbl!.addEventListener('row-click', (evt): void => { - // @ts-ignore - if (evt.detail.flag === 'thread') { - // @ts-ignore - scatterData = evt.detail.children; - // @ts-ignore - str = evt.detail.thread; - this.render(scatterData, str, []); - } - // @ts-ignore - if (evt.detail.flag === 'cycle' && evt.detail.pid === scatterData[evt.detail.id - 1].pid && evt.detail.tid === scatterData[evt.detail.id - 1].tid) { - // @ts-ignore - SegMenTaTion.tabHover('CPU-FREQ', true, evt.detail.id - 1); - - } - }); - this.scatterInput = this.shadowRoot?.querySelector('.chart-box'); - this.shadowRoot?.querySelector('#query-btn')!.addEventListener('click', (e) => { - // @ts-ignore - let cycleAStartValue = this.shadowRoot?.querySelector('#cycle-a-start-range')!.value; - // @ts-ignore - let cycleAEndValue = this.shadowRoot?.querySelector('#cycle-a-end-range')!.value; - // @ts-ignore - let cycleBStartValue = this.shadowRoot?.querySelector('#cycle-b-start-range')!.value; - // @ts-ignore - let cycleBEndValue = this.shadowRoot?.querySelector('#cycle-b-end-range')!.value; - let queryCycleScatter = [Number(cycleAStartValue), Number(cycleAEndValue), Number(cycleBStartValue), Number(cycleBEndValue)]; - this.render(scatterData, str, queryCycleScatter); - }) - } - - connectedCallback(): void { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.threadStatesTbl!); - } - - initHtml(): string { - return ` + initElements(): void { + this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-running-percent'); + // 暂时屏蔽列排序功能,后续增加则重写排序方法 + this.threadStatesDIV = this.shadowRoot?.querySelector('#dataCut'); + this.threadStatesDIV?.children[2].children[0].addEventListener('click', (e) => { + this.threadStatesTbl!.loading = true; + this.dataSingleCut(this.threadStatesDIV?.children[0], this.threadStatesDIV?.children[1], this.initData); + }); + this.threadStatesDIV?.children[2].children[1].addEventListener('click', (e) => { + this.threadStatesTbl!.loading = true; + this.dataLoopCut(this.threadStatesDIV?.children[0], this.threadStatesDIV?.children[1], this.initData); + }); + } + connectedCallback() { + super.connectedCallback(); + resizeObserver(this.parentElement!, this.threadStatesTbl!); + } + initHtml(): string { + return `
    @@ -854,61 +259,765 @@ export class TabPaneFreqDataCut extends BaseElement {
    - - -
    - - - - - - - - - - - - - - - - - - -
    - -
    -
    - maxFreq: - - Fps: - -
    -
    -
    - - -
    -
    -
    - ` + + + + + + + + + + + + + + + + + + + `; + } + sortByColumn(treadStateDetail: any) { + function compare(property: any, treadStatesSort: any, type: any) { + return function (threadStatesLeftData: SelectionData | any, threadStatesRightData: SelectionData | any) { + if (threadStatesLeftData.process == ' ' || threadStatesRightData.process == ' ') { + return 0; + } + if (type === 'number') { + return treadStatesSort === 2 + ? parseFloat(threadStatesRightData[property]) - parseFloat(threadStatesLeftData[property]) + : parseFloat(threadStatesLeftData[property]) - parseFloat(threadStatesRightData[property]); + } else { + if (threadStatesRightData[property] > threadStatesLeftData[property]) { + return treadStatesSort === 2 ? 1 : -1; + } else if (threadStatesRightData[property] == threadStatesLeftData[property]) { + return 0; + } else { + return treadStatesSort === 2 ? -1 : 1; + } + } + }; + } + + if (treadStateDetail.key === 'name' || treadStateDetail.key === 'thread' || treadStateDetail.key === 'state') { + this.threadStatesTblSource.sort(compare(treadStateDetail.key, treadStateDetail.sort, 'string')); + } else { + this.threadStatesTblSource.sort(compare(treadStateDetail.key, treadStateDetail.sort, 'number')); } -} \ No newline at end of file + this.threadStatesTbl!.recycleDataSource = this.threadStatesTblSource; + } + // single方式切割数据功能 + dataSingleCut(threadId: any, threadFunc: any, resultList: any) { + threadId.style.border = '1px solid rgb(151,151,151)'; + threadFunc.style.border = '1px solid rgb(151,151,151)'; + let threadIdValue = threadId.value.trim(); + let threadFuncName = threadFunc.value.trim(); + let leftNS = this.currentSelectionParam.leftNs; + let rightNS = this.currentSelectionParam.rightNs; + let tableValue: any = this.threadStatesTbl; + tableValue.value = []; + if (threadIdValue != '' && threadFuncName != '') { + // 根据用户输入的线程ID,方法名去查询数据库,得到对应的方法起始时间,持续时间等数据,以便作为依据进行后续数据切割 + querySearchFuncData(threadFuncName, Number(threadIdValue), leftNS, rightNS).then((result) => { + if (result != null && result.length > 0) { + let targetMap = new Map(); + // 新创建map对象接收传过来的实参map + resultList.forEach((item: any, key: any) => { + targetMap.set(key, JSON.parse(JSON.stringify(item))); + }); + let timeDur = this.currentSelectionParam.recordStartNs; + // 周期切割依据数据整理 + let dealArr = new Array(); + for (let i of result) { + if (i.startTime + timeDur + i.dur < this.currentSelectionParam.rightNs + timeDur) { + dealArr.push({ ts: i.startTime + timeDur, dur: i.dur }); + } + } + let cycleMap = new Map(); + let totalList = new Map(); + targetMap.forEach((item, key) => { + cycleMap.set(key, new Array()); + totalList.set(key, new Array()); + for (let i = 0; i < dealArr.length; i++) { + let cpuArr = new Array(); + let cpuMap = new Map(); + let resList = new Array(); + // 时间由纳秒转换为秒的倍数 + const multiple = 1000000000; + // 算力倍数值 + const countMutiple = 1000; + cpuMap.set(key, new Array()); + cycleMap + .get(key) + .push({ + thread: '周期' + (i + 1) + '—' + item[0].thread, + ts: (dealArr[i].ts - timeDur) / multiple, + count: 0, + cpu: '', + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); + let value = JSON.parse(JSON.stringify(item)); + for (let j = 0; j < value.length; j++) { + value[j].ts = value[j].ts * multiple; + value[j].freq = value[j].freq == 'unknown' ? 0 : value[j].freq; + if (!cpuArr.includes(value[j].cpu)) { + cpuArr.push(value[j].cpu); + cpuMap + .get(key) + .push({ + thread: '周期' + (i + 1) + '—' + value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: 0, + cpu: value[j].cpu, + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); + } + if (dealArr[i].ts < value[j].ts) { + if (dealArr[i].ts + dealArr[i].dur > value[j].ts) { + if (dealArr[i].ts + dealArr[i].dur > value[j].ts + value[j].dur) { + resList.push({ + thread: '周期' + (i + 1) + '—' + value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (value[j].freq * value[j].dur) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: value[j].dur, + percent: value[j].percent, + state: 'Running', + id: i, + }); + totalList + .get(key) + .push({ + thread: value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (value[j].freq * value[j].dur) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: value[j].dur, + percent: value[j].percent, + state: 'Running', + id: i, + }); + } else { + resList.push({ + thread: '周期' + (i + 1) + '—' + value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: ((dealArr[i].ts + dealArr[i].dur - value[j].ts) * value[j].freq) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: dealArr[i].ts + dealArr[i].dur - value[j].ts, + percent: ((dealArr[i].ts + dealArr[i].dur - value[j].ts) / value[j].dur) * value[j].percent, + state: 'Running', + id: i, + }); + totalList + .get(key) + .push({ + thread: value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: ((dealArr[i].ts + dealArr[i].dur - value[j].ts) * value[j].freq) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: dealArr[i].ts + dealArr[i].dur - value[j].ts, + percent: ((dealArr[i].ts + dealArr[i].dur - value[j].ts) / value[j].dur) * value[j].percent, + state: 'Running', + id: i, + }); + break; + } + } + } else { + if (value[j].ts + value[j].dur > dealArr[i].ts) { + if (value[j].ts + value[j].dur > dealArr[i].ts + dealArr[i].dur) { + resList.push({ + thread: '周期' + (i + 1) + '—' + value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (dealArr[i].dur * value[j].freq) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: dealArr[i].dur, + percent: (dealArr[i].dur / value[j].dur) * value[j].percent, + state: 'Running', + id: i, + }); + totalList + .get(key) + .push({ + thread: value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (dealArr[i].dur * value[j].freq) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: dealArr[i].dur, + percent: (dealArr[i].dur / value[j].dur) * value[j].percent, + state: 'Running', + id: i, + }); + break; + } else { + resList.push({ + thread: '周期' + (i + 1) + '—' + value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: ((value[j].ts + value[j].dur - dealArr[i].ts) * value[j].freq) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: value[j].ts + value[j].dur - dealArr[i].ts, + percent: ((value[j].ts + value[j].dur - dealArr[i].ts) / value[j].dur) * value[j].percent, + state: 'Running', + id: i, + }); + totalList + .get(key) + .push({ + thread: value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: ((value[j].ts + value[j].dur - dealArr[i].ts) * value[j].freq) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: value[j].ts + value[j].dur - dealArr[i].ts, + percent: ((value[j].ts + value[j].dur - dealArr[i].ts) / value[j].dur) * value[j].percent, + state: 'Running', + id: i, + }); + } + } + } + } + this.mergeData(resList); + resList.sort((a, b) => b.count - a.count); + cpuMap.get(key).sort((a: any, b: any) => a.cpu - b.cpu); + cpuMap.get(key).forEach((item: any) => { + for (let s = 0; s < resList.length; s++) { + if (item.cpu == resList[s].cpu) { + item.children.push(resList[s]); + item.count += resList[s].count; + item.dur += resList[s].dur; + item.percent += resList[s].percent; + } + } + }); + // 将cpu数据放置到对应周期层级下 + this.mergeCycleData(cycleMap.get(key)[i], cpuMap.get(key)); + } + }); + // 拷贝线程数组,防止数据污染 + let threadArr = JSON.parse(JSON.stringify(this.threadArr)); + // 拷贝进程数组,防止数据污染 + let processArr = JSON.parse(JSON.stringify(this.processArr)); + // 将周期层级防止到线程层级下 + this.mergeThreadData(threadArr, cycleMap); + // 将原始数据放置到对应的线程层级下,周期数据前 + let totalData = this.merge(totalList); + this.mergeTotalData(threadArr, totalData); + // 合并数据到进程层级下 + this.mergePidData(processArr, threadArr); + this.fixedDeal(processArr); + this.threadStatesTblSource = processArr; + this.threadStatesTbl!.recycleDataSource = processArr; + this.threadStatesTbl!.loading = false; + this.threadClick(processArr); + } else { + this.threadStatesTblSource = []; + this.threadStatesTbl!.recycleDataSource = []; + this.threadStatesTbl!.loading = false; + } + }); + } else { + this.threadStatesTbl!.loading = false; + if (threadIdValue == '') { + threadId.style.border = '1px solid rgb(255,0,0)'; + threadId.setAttribute('placeholder', 'Please input thread id'); + } + if (threadFuncName == '') { + threadFunc.style.border = '1px solid rgb(255,0,0)'; + threadFunc.setAttribute('placeholder', 'Please input function name'); + } + } + } + // Loop方式切割数据功能 + dataLoopCut(threadId: any, threadFunc: any, resultList: any) { + threadId.style.border = '1px solid rgb(151,151,151)'; + threadFunc.style.border = '1px solid rgb(151,151,151)'; + let threadIdValue = threadId.value.trim(); + let threadFuncName = threadFunc.value.trim(); + let leftNS = this.currentSelectionParam.leftNs; + let rightNS = this.currentSelectionParam.rightNs; + let tableValue: any = this.threadStatesTbl; + tableValue.value = []; + if (threadIdValue != '' && threadFuncName != '') { + querySearchFuncData(threadFuncName, Number(threadIdValue), leftNS, rightNS).then((res) => { + if (res != null && res.length > 0) { + let targetMap = new Map(); + // 新创建map对象接收传过来的实参map + resultList.forEach((item: any, key: any) => { + targetMap.set(key, JSON.parse(JSON.stringify(item))); + }); + let timeDur = this.currentSelectionParam.recordStartNs; + let cutArr = new Array(); + // 根据线程id及方法名获取的数据,处理后用作切割时间依据,时间跨度为整个方法开始时间到末个方法开始时间 + for (let i of res) { + cutArr.push({ ts: i.startTime + timeDur }); + } + let cycleMap = new Map(); + let totalList = new Map(); + targetMap.forEach((item, key) => { + cycleMap.set(key, new Array()); + totalList.set(key, new Array()); + for (let i = 0; i < cutArr.length - 1; i++) { + let cpuArr = new Array(); + let cpuMap = new Map(); + let resList = new Array(); + // 时间由纳秒转换为秒的倍数 + const multiple = 1000000000; + // 算力倍数值 + const countMutiple = 1000; + cpuMap.set(key, new Array()); + cycleMap + .get(key) + .push({ + thread: '周期' + (i + 1) + '—' + item[0].thread, + ts: (cutArr[i].ts - timeDur) / multiple, + count: 0, + cpu: '', + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); + let value = JSON.parse(JSON.stringify(item)); + for (let j = 0; j < value.length; j++) { + value[j].ts = value[j].ts * multiple; + value[j].freq = value[j].freq == 'unknown' ? 0 : value[j].freq; + if (!cpuArr.includes(value[j].cpu)) { + cpuArr.push(value[j].cpu); + cpuMap + .get(key) + .push({ + thread: '周期' + (i + 1) + '—' + value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: 0, + cpu: value[j].cpu, + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); + } + if (value[j].ts >= cutArr[i].ts) { + if (value[j].ts + value[j].dur <= cutArr[i + 1].ts) { + resList.push({ + thread: '周期' + (i + 1) + '—' + value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (value[j].freq * value[j].dur) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: value[j].dur, + percent: value[j].percent, + state: 'Running', + id: i, + }); + totalList + .get(key) + .push({ + thread: value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (value[j].freq * value[j].dur) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: value[j].dur, + percent: value[j].percent, + state: 'Running', + id: i, + }); + } else { + if (cutArr[i + 1].ts - value[j].ts > 0) { + resList.push({ + thread: '周期' + (i + 1) + '—' + value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (value[j].freq * (cutArr[i + 1].ts - value[j].ts)) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: cutArr[i + 1].ts - value[j].ts, + percent: value[j].percent * ((cutArr[i + 1].ts - value[j].ts) / value[j].dur), + state: 'Running', + id: i, + }); + totalList + .get(key) + .push({ + thread: value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (value[j].freq * (cutArr[i + 1].ts - value[j].ts)) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: cutArr[i + 1].ts - value[j].ts, + percent: value[j].percent * ((cutArr[i + 1].ts - value[j].ts) / value[j].dur), + state: 'Running', + id: i, + }); + break; + } + } + } else { + if (value[j].ts + value[j].dur > cutArr[i + 1].ts) { + resList.push({ + thread: '周期' + (i + 1) + '—' + value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (value[j].freq * (cutArr[i + 1].ts - cutArr[i].ts)) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: cutArr[i + 1].ts - cutArr[i].ts, + percent: value[j].percent * ((cutArr[i + 1].ts - cutArr[i].ts) / value[j].dur), + state: 'Running', + id: i, + }); + totalList + .get(key) + .push({ + thread: value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (value[j].freq * (cutArr[i + 1].ts - cutArr[i].ts)) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: cutArr[i + 1].ts - cutArr[i].ts, + percent: value[j].percent * ((cutArr[i + 1].ts - cutArr[i].ts) / value[j].dur), + state: 'Running', + id: i, + }); + } + if (value[j].ts + value[j].dur > cutArr[i].ts && value[j].ts + value[j].dur < cutArr[i + 1].ts) { + resList.push({ + thread: '周期' + (i + 1) + '—' + value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (value[j].freq * (value[j].dur + value[j].ts - cutArr[i].ts)) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: value[j].dur + value[j].ts - cutArr[i].ts, + percent: value[j].percent * ((value[j].dur + value[j].ts - cutArr[i].ts) / value[j].dur), + state: 'Running', + id: i, + }); + totalList + .get(key) + .push({ + thread: value[j].thread, + pid: value[j].pid, + tid: value[j].tid, + count: (value[j].freq * (value[j].dur + value[j].ts - cutArr[i].ts)) / countMutiple, + cpu: value[j].cpu, + freq: value[j].freq, + dur: value[j].dur + value[j].ts - cutArr[i].ts, + percent: value[j].percent * ((value[j].dur + value[j].ts - cutArr[i].ts) / value[j].dur), + state: 'Running', + id: i, + }); + } + } + } + // 合并相同周期内的数据 + this.mergeData(resList); + // 以算力消耗降序排列 + resList.sort((a, b) => b.count - a.count); + // 以cpu升序排列 + cpuMap.get(key).sort((a: any, b: any) => a.cpu - b.cpu); + cpuMap.get(key).forEach((item: any) => { + for (let s = 0; s < resList.length; s++) { + if (item.cpu == resList[s].cpu) { + item.children.push(resList[s]); + item.count += resList[s].count; + item.dur += resList[s].dur; + item.percent += resList[s].percent; + } + } + }); + // 将cpu数据放置到对应周期层级下 + this.mergeCycleData(cycleMap.get(key)[i], cpuMap.get(key)); + } + }); + let threadArr = JSON.parse(JSON.stringify(this.threadArr)); + let processArr = JSON.parse(JSON.stringify(this.processArr)); + this.mergeThreadData(threadArr, cycleMap); + let totalData = this.merge(totalList); + this.mergeTotalData(threadArr, totalData); + this.mergePidData(processArr, threadArr); + this.fixedDeal(processArr); + this.threadStatesTblSource = processArr; + this.threadStatesTbl!.recycleDataSource = processArr; + this.threadStatesTbl!.setStatus(processArr, true); + this.threadStatesTbl!.loading = false; + this.threadClick(processArr); + } else { + this.threadStatesTblSource = []; + this.threadStatesTbl!.recycleDataSource = []; + this.threadStatesTbl!.loading = false; + } + }); + } else { + this.threadStatesTbl!.loading = false; + if (threadIdValue == '') { + threadId.style.border = '1px solid rgb(255,0,0)'; + threadId.setAttribute('placeholder', 'Please input thread id'); + } + if (threadFuncName == '') { + threadFunc.style.border = '1px solid rgb(255,0,0)'; + threadFunc.setAttribute('placeholder', 'Please input function name'); + } + } + } + mergeFreqData(needDeal: any, dealArr: any, sum: number) { + needDeal.forEach((value: any, key: any) => { + let resultList = new Array(); + // 时间由纳秒转换为秒的倍数 + const multiple = 1000000000; + // 算力倍数值 + const countMutiple = 1000; + for (let i = 0; i < value.length; i++) { + for (let j = 0; j < dealArr.length; j++) { + if (value[i].cpu == dealArr[j].cpu) { + if (value[i].ts > dealArr[j].startNS) { + if (value[i].ts < dealArr[j].startNS + dealArr[j].dur) { + if (value[i].dur < dealArr[j].startNS + dealArr[j].dur - value[i].ts) { + resultList.push({ + thread: value[i].thread, + pid: value[i].pid, + tid: value[i].tid, + count: (dealArr[j].value * value[i].dur) / countMutiple, + cpu: value[i].cpu, + freq: dealArr[j].value, + dur: value[i].dur, + percent: (value[i].dur / sum) * 100, + state: 'Running', + ts: value[i].ts / multiple, + }); + break; + } else { + resultList.push({ + thread: value[i].thread, + pid: value[i].pid, + tid: value[i].tid, + count: (dealArr[j].value * (dealArr[j].startNS + dealArr[j].dur - value[i].ts)) / countMutiple, + cpu: value[i].cpu, + freq: dealArr[j].value, + dur: dealArr[j].startNS + dealArr[j].dur - value[i].ts, + percent: ((dealArr[j].startNS + dealArr[j].dur - value[i].ts) / sum) * 100, + state: 'Running', + ts: value[i].ts / multiple, + }); + } + } + } else { + if (value[i].ts + value[i].dur > dealArr[j].startNS) { + if (value[i].dur + value[i].ts - dealArr[j].startNS < dealArr[j].dur) { + resultList.push({ + thread: value[i].thread, + pid: value[i].pid, + tid: value[i].tid, + count: (dealArr[j].value * (value[i].dur + value[i].ts - dealArr[j].startNS)) / countMutiple, + cpu: value[i].cpu, + freq: dealArr[j].value, + dur: value[i].dur + value[i].ts - dealArr[j].startNS, + percent: ((value[i].dur + value[i].ts - dealArr[j].startNS) / sum) * 100, + state: 'Running', + ts: dealArr[j].startNS / multiple, + }); + break; + } else { + resultList.push({ + thread: value[i].thread, + pid: value[i].pid, + tid: value[i].tid, + count: (dealArr[j].value * dealArr[j].dur) / countMutiple, + cpu: value[i].cpu, + freq: dealArr[j].value, + dur: dealArr[j].dur, + percent: (dealArr[j].dur / sum) * 100, + state: 'Running', + ts: dealArr[j].startNS / multiple, + }); + } + } else { + resultList.push({ + thread: value[i].thread, + pid: value[i].pid, + tid: value[i].tid, + count: 0, + cpu: value[i].cpu, + freq: 'unknown', + dur: value[i].dur, + percent: (value[i].dur / sum) * 100, + state: 'Running', + ts: value[i].ts / multiple, + }); + break; + } + } + } + } + } + this.initData.set(key, JSON.parse(JSON.stringify(resultList))); + }); + } + mergeThreadData(threadArr: any, cpuMap: any) { + for (let i = 0; i < threadArr.length; i++) { + let cpuMapData = cpuMap.get(threadArr[i].pid + '_' + threadArr[i].tid); + for (let j = 0; j < cpuMapData.length; j++) { + threadArr[i].children.push(cpuMapData[j]); + threadArr[i].count += cpuMapData[j].count; + threadArr[i].dur += cpuMapData[j].dur; + threadArr[i].percent += cpuMapData[j].percent; + } + } + } + mergePidData(pidArr: any, threadArr: any) { + for (let i = 0; i < pidArr.length; i++) { + for (let j = 0; j < threadArr.length; j++) { + if (pidArr[i].pid == threadArr[j].pid) { + pidArr[i].children.push(threadArr[j]); + pidArr[i].count += threadArr[j].count; + pidArr[i].dur += threadArr[j].dur; + pidArr[i].percent += threadArr[j].percent; + } + } + } + } + mergeData(resList: any) { + // 合并相同周期内的数据 + for (let i = 0; i < resList.length; i++) { + for (let j = i + 1; j < resList.length; j++) { + if ( + resList[i].cpu === resList[j].cpu && + resList[i].freq === resList[j].freq && + resList[i].id === resList[j].id + ) { + resList[i].dur += resList[j].dur; + resList[i].percent += resList[j].percent; + resList[i].count += resList[j].count; + resList.splice(j, 1); + j--; + } + } + } + } + mergeCycleData(obj: any, arr: any) { + for (let i = 0; i < arr.length; i++) { + if (arr[i].count === 0 && arr[i].dur === 0) { + continue; + } + obj.children.push(arr[i]); + obj.count += arr[i].count; + obj.dur += arr[i].dur; + obj.percent += arr[i].percent; + } + } + mergeTotalData(threadArr: any, totalData: any) { + for (let i = 0; i < threadArr.length; i++) { + for (let j = 0; j < totalData.length; j++) { + if (threadArr[i].pid == totalData[j].pid && threadArr[i].tid == totalData[j].tid) { + totalData[j].thread = 'TotalData'; + threadArr[i].children.unshift(totalData[j]); + } + } + } + } + fixedDeal(arr: any) { + if (arr == undefined) { + return; + } + for (let i = 0; i < arr.length; i++) { + arr[i].percent = arr[i].percent > 100 ? 100 : arr[i].percent; + arr[i].percent = arr[i].percent.toFixed(2); + this.fixedDeal(arr[i].children); + } + } + merge(totalList: any) { + let result = new Array(); + totalList.forEach((value: any, key: any) => { + let countNum = result.push({ + thread: '', + pid: key.split('_')[0], + tid: key.split('_')[1], + count: 0, + cpu: '', + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); + let cpuArr = new Array(); + let flagArr = new Array(); + for (let i = 0; i < value.length; i++) { + if (!flagArr.includes(value[i].cpu)) { + flagArr.push(value[i].cpu); + let flag = cpuArr.push({ + thread: value[i].thread, + pid: value[i].pid, + tid: value[i].tid, + count: 0, + cpu: value[i].cpu, + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); + result[countNum - 1].children.push(cpuArr[flag - 1]); + } + for (let j = i + 1; j < value.length; j++) { + if (value[i].cpu === value[j].cpu && value[i].freq === value[j].freq) { + value[i].dur += value[j].dur; + value[i].percent += value[j].percent; + value[i].count += value[j].count; + value.splice(j, 1); + j--; + } + } + } + result[countNum - 1].children.sort((a: any, b: any) => a.cpu - b.cpu); + for (let i = 0; i < cpuArr.length; i++) { + for (let j = 0; j < value.length; j++) { + if (cpuArr[i].cpu == value[j].cpu) { + cpuArr[i].children.push(value[j]); + cpuArr[i].dur += value[j].dur; + cpuArr[i].count += value[j].count; + cpuArr[i].percent += value[j].percent; + } + } + result[countNum - 1].dur += cpuArr[i].dur; + result[countNum - 1].count += cpuArr[i].count; + result[countNum - 1].percent += cpuArr[i].percent; + } + }); + return result; + } +} diff --git a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts index 8814bed80..3cfd8e96c 100644 --- a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts +++ b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts @@ -16,304 +16,347 @@ import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../StackBar.js' +import '../../../StackBar.js'; import { getTabRunningPercent, queryCpuFreqUsageData, queryCpuFreqFilterId } from '../../../../database/SqlLite.js'; import { Utils } from '../../base/Utils.js'; import { resizeObserver } from '../SheetUtils.js'; import { SliceGroup } from '../../../../bean/StateProcessThread.js'; -import { SegMenTaTion } from "../../../chart/SpSegmentationChart.js"; -import { TabPaneFreqUsageConfig, TabPaneRunningConfig, TabPaneCpuFreqConfig } from "./TabPaneFreqUsageConfig.js"; @element('tabpane-frequsage') export class TabPaneFreqUsage extends BaseElement { - private threadStatesTbl: LitTable | null | undefined; - private threadStatesTblSource: Array = []; - private currentSelectionParam: Selection | undefined; - private threadArr: Array = []; + private threadStatesTbl: LitTable | null | undefined; + private threadStatesTblSource: Array = []; + private currentSelectionParam: Selection | undefined; - set data(threadStatesParam: SelectionParam | any) { - if (this.currentSelectionParam === threadStatesParam) { - return; - } - this.threadStatesTbl!.loading = true; - this.currentSelectionParam = threadStatesParam; - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - let tableValue: any = this.threadStatesTbl; - tableValue.value = []; - this.threadArr = []; - this.init(threadStatesParam); - } - /** - * 初始化数据 - */ - async init(threadStatesParam: SelectionParam | any): Promise { - let [runningData, sum] = await this.queryRunningData(threadStatesParam); - let cpuFreqData: Array = await this.queryCpuFreqData(threadStatesParam); - let cpuMap: Map> = new Map(); - if (runningData.size > 0) { - // 创建进程级的数组 - let pidArr: Array = [], processArr: Array = threadStatesParam.processIds.length > 1 ? [...new Set(threadStatesParam.processIds)] : threadStatesParam.processIds; - for (let i of processArr) { - pidArr.push(new TabPaneFreqUsageConfig(Utils.PROCESS_MAP.get(i) === null ? 'Process ' + i : Utils.PROCESS_MAP.get(i) + ' ' + i, '', i, '', 0, '', '', 0, '', 0, 'process', -1, [])); - } - // 将cpu频点数据与running状态数据整合,保证其上该段时长内有对应的cpu频点数据 - this.mergeFreqData(runningData, cpuMap, cpuFreqData, sum, threadStatesParam); - // 将频点数据放置到对应cpu层级下 - this.mergeCpuData(cpuMap, runningData); - // 将cpu层级数据放置到线程分组下 - this.mergeThreadData(this.threadArr, cpuMap); - // 将线程层级数据放置到进程级分组下 - this.mergePidData(pidArr, this.threadArr); - // 百分比保留两位小数 - this.fixedDeal(pidArr) - this.threadStatesTblSource = pidArr; - this.threadStatesTbl!.recycleDataSource = pidArr; - this.threadStatesTbl!.loading = false; - this.theadClick(pidArr); - this.threadStatesTbl!.loading = false; - } else { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - } - } - /** - * 查询cpu频点信息 - */ - async queryCpuFreqData(threadStatesParam: SelectionParam | any): Promise> { - // 查询cpu及id信息 - let result: Array = await queryCpuFreqFilterId(); - // 以键值对形式将cpu及id进行对应,后续会将频点数据与其对应cpu进行整合 - let IdMap: Map = new Map(); - let queryId: Array = []; - for (let i = 0; i < result.length; i++) { - queryId.push(result[i].id); - IdMap.set(result[i].id, result[i].cpu); - } - let dealArr: Array = []; - // 通过id去查询频点数据 - let res: Array = await queryCpuFreqUsageData(queryId); - for (let i of res) { - let obj = new TabPaneCpuFreqConfig(i.startNS + threadStatesParam.recordStartNs, IdMap.get(i.filter_id)!, i.value, i.dur) - dealArr.push(obj); - } - return dealArr; + set data(threadStatesParam: SelectionParam | any) { + if (this.currentSelectionParam === threadStatesParam) { + return; } - - /** - * 查询框选区域内的所有running状态数据 - */ - async queryRunningData(threadStatesParam: SelectionParam | any): Promise> { - // 查询running状态线程数据 - let result: Array = await getTabRunningPercent(threadStatesParam.threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs); - let needDeal: Map> = new Map(), sum: number = 0; - if (result != null && result.length > 0) { - // 将running线程数据存到map中 - for (let e of result) { - if(threadStatesParam.processIds.includes(e.pid)){ - if (needDeal.get(e.pid + '_' + e.tid) === undefined) { - this.threadArr.push(new TabPaneFreqUsageConfig(Utils.THREAD_MAP.get(e.tid) + ' ' + e.tid, '', e.pid, e.tid, 0, '', '', 0, '', 0, 'thread', -1, [])); - needDeal.set(e.pid + '_' + e.tid, new Array()); - } - if ((e.ts < (threadStatesParam.leftNs + threadStatesParam.recordStartNs)) && ((e.ts + e.dur) > (threadStatesParam.leftNs + threadStatesParam.recordStartNs))) { - const ts = e.ts; - e.ts = threadStatesParam.leftNs + threadStatesParam.recordStartNs; - e.dur = ts + e.dur - (threadStatesParam.leftNs + threadStatesParam.recordStartNs); - } - if ((e.ts + e.dur) > (threadStatesParam.rightNs + threadStatesParam.recordStartNs)) { - e.dur = threadStatesParam.rightNs + threadStatesParam.recordStartNs - e.ts; - } - let process = Utils.PROCESS_MAP.get(e.pid); - let thread = Utils.THREAD_MAP.get(e.tid); - e.process = process == null || process.length == 0 ? '[NULL]' : process; - e.thread = thread == null || thread.length == 0 ? '[NULL]' : thread; - let arr: any = needDeal.get(e.pid + '_' + e.tid); - sum += e.dur; - arr.push(e); - } - } - } - return [needDeal, sum]; - } - - /** - * 整合running数据与频点数据 - */ - mergeFreqData(needDeal: Map>, cpuMap: Map>, dealArr: Array, sum: number, threadStatesParam: SelectionParam | any): void { - needDeal.forEach((value: Array, key: string) => { - let resultList: Array = [], cpuArr: Array = []; - cpuMap.set(key, new Array()); - const multiple: number = 1000; - for (let i = 0; i < value.length; i++) { - if (!cpuArr.includes(value[i].cpu)) { - cpuArr.push(value[i].cpu); - cpuMap.get(key)?.push(new TabPaneFreqUsageConfig(value[i].tid + '_' + Utils.THREAD_MAP.get(value[i].tid), '', value[i].pid, value[i].tid, 0, value[i].cpu, '', 0, '', 0, 'cpu', -1, [])); - } - for (let j = 0; j < dealArr.length; j++) { - const consumption = SegMenTaTion.freqInfoMapData.size > 0 ? SegMenTaTion.freqInfoMapData.get(value[i].cpu).get(dealArr[j].value) : dealArr[j].value; - // 只需要合并相同cpu的数据 - if (value[i].cpu === dealArr[j].cpu) { - // 当running状态数据的开始时间大于频点数据开始时间,小于频点结束时间。且running数据的持续时间小于频点结束时间减去running数据开始时间的差值的情况 - if (value[i].ts > dealArr[j].startNS && value[i].ts < (dealArr[j].startNS + dealArr[j].dur) && value[i].dur < (dealArr[j].startNS + dealArr[j].dur - value[i].ts)) { - resultList.push(new TabPaneFreqUsageConfig(value[i].tid + '_' + value[i].thread, value[i].ts, '', '', (consumption * value[i].dur) / multiple, value[i].cpu, dealArr[j].value, value[i].dur, '', value[i].dur / sum * 100, 'freqdata', -1, undefined)); - break; - } - // 当running状态数据的开始时间大于频点数据开始时间,小于频点结束时间。且running数据的持续时间大于等于频点结束时间减去running数据开始时间的差值的情况 - if (value[i].ts > dealArr[j].startNS && value[i].ts < (dealArr[j].startNS + dealArr[j].dur) && value[i].dur >= (dealArr[j].startNS + dealArr[j].dur - value[i].ts)) { - resultList.push(new TabPaneFreqUsageConfig(value[i].tid + '_' + value[i].thread, value[i].ts, '', '', (consumption * (dealArr[j].startNS + dealArr[j].dur - value[i].ts)) / multiple, value[i].cpu, dealArr[j].value, (dealArr[j].startNS + dealArr[j].dur - value[i].ts), '', (dealArr[j].startNS + dealArr[j].dur - value[i].ts) / sum * 100, 'freqdata', -1, undefined)); - } - // 当running状态数据的开始时间小于等于频点数据开始时间,结束时间大于频点开始时间。且running数据的持续时间减去频点数据开始时间的差值小于频点数据持续时间的情况 - if (value[i].ts <= dealArr[j].startNS && (value[i].ts + value[i].dur) > dealArr[j].startNS && (value[i].dur + value[i].ts - dealArr[j].startNS) < dealArr[j].dur) { - resultList.push(new TabPaneFreqUsageConfig(value[i].tid + '_' + value[i].thread, dealArr[j].startNS, '', '', (consumption * (value[i].dur + value[i].ts - dealArr[j].startNS)) / multiple, value[i].cpu, dealArr[j].value, (value[i].dur + value[i].ts - dealArr[j].startNS), '', (value[i].dur + value[i].ts - dealArr[j].startNS) / sum * 100, 'freqdata', -1, undefined)); - break; - } - // 当running状态数据的开始时间小于等于频点数据开始时间,结束时间大于频点开始时间。且running数据的持续时间减去频点数据开始时间的差值大于等于频点数据持续时间的情况 - if (value[i].ts <= dealArr[j].startNS && (value[i].ts + value[i].dur) > dealArr[j].startNS && (value[i].dur + value[i].ts - dealArr[j].startNS) >= dealArr[j].dur) { - resultList.push(new TabPaneFreqUsageConfig(value[i].tid + '_' + value[i].thread, dealArr[j].startNS, '', '', (consumption * dealArr[j].dur) / multiple, value[i].cpu, dealArr[j].value, dealArr[j].dur, '', dealArr[j].dur / sum * 100, 'freqdata', -1, undefined)); - } - // 当running状态数据的开始时间小于等于频点数据开始时间,结束时间小于等于频点开始时间的情况 - if (value[i].ts <= dealArr[j].startNS && (value[i].ts + value[i].dur) <= dealArr[j].startNS){ - resultList.push(new TabPaneFreqUsageConfig(value[i].tid + '_' + value[i].thread, value[i].ts, '', '', 0, value[i].cpu, 'unknown', value[i].dur, '', value[i].dur / sum * 100, 'freqdata', -1, undefined)); - break; - } - } - } - } - cpuMap.get(key)?.sort((a: any, b: any) => a.cpu - b.cpu); - needDeal.set(key, this.mergeData(resultList, threadStatesParam)); - }) - } - - /** - * 合并同一线程内,当运行所在cpu和频点相同时,dur及percent进行累加求和 - */ - mergeData(resultList: Array, threadStatesParam: SelectionParam | any): Array{ - for (let i = 0; i < resultList.length; i++) { - for (let j = i + 1; j < resultList.length; j++) { - if (resultList[i].cpu === resultList[j].cpu && resultList[i].freq === resultList[j].freq) { - resultList[i].dur += resultList[j].dur; - resultList[i].percent += resultList[j].percent; - resultList[i].count += resultList[j].count; - resultList.splice(j, 1); - j--; + this.threadStatesTbl!.loading = true; + this.currentSelectionParam = threadStatesParam; + this.threadStatesTblSource = []; + this.threadStatesTbl!.recycleDataSource = []; + let tableValue: any = this.threadStatesTbl; + tableValue.value = []; + // 查询框选区域内的状态为running的数据 + getTabRunningPercent(threadStatesParam.threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs).then( + (result) => { + // 查询该trace文件中的cpu核数及id + queryCpuFreqFilterId().then((r) => { + // 将查询结果以键值对形式存入Map对象,仪表后续将频点数据与Cpu进行关联 + let IdMap = new Map(); + let queryId = new Array(); + for (let i = 0; i < r.length; i++) { + queryId.push(r[i].id); + IdMap.set(r[i].id, r[i].cpu); + } + // 通过cpu的id去查询总的cpu频点数据 + queryCpuFreqUsageData(queryId).then((res) => { + if (result != null && result.length > 0) { + let sum = 0; + let dealArr = new Array(); + // 将cpu频点数据进行整合 + for (let i of res) { + dealArr.push({ + startNS: i.startNS + threadStatesParam.recordStartNs, + dur: i.dur, + value: i.value, + cpu: IdMap.get(i.filter_id), + }); + } + let needDeal = new Map(); + let cpuMap = new Map(); + let pidArr = new Array(); + let threadArr = new Array(); + // 创建进程级的数组 + let processArr: any = + threadStatesParam.processIds.length > 1 + ? [...new Set(threadStatesParam.processIds)] + : threadStatesParam.processIds; + for (let i of processArr) { + pidArr.push({ + process: Utils.PROCESS_MAP.get(i) == null ? 'Process ' + i : Utils.PROCESS_MAP.get(i) + ' ' + i, + thread: Utils.PROCESS_MAP.get(i) == null ? 'Process ' + i : Utils.PROCESS_MAP.get(i) + ' ' + i, + pid: i, + tid: '', + count: 0, + cpu: '', + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); + } + // 将running线程数据存到map中 + for (let e of result) { + if (processArr.includes(e.pid) && e.state == 'Running') { + if (needDeal.get(e.pid + '_' + e.tid) == undefined) { + threadArr.push({ + process: + Utils.PROCESS_MAP.get(e.pid) == null + ? 'Process ' + e.pid + : Utils.PROCESS_MAP.get(e.pid) + ' ' + e.pid, + thread: Utils.THREAD_MAP.get(e.tid) + ' ' + e.tid, + pid: e.pid, + tid: e.tid, + count: 0, + cpu: '', + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); + needDeal.set(e.pid + '_' + e.tid, new Array()); + } + if ( + e.ts < threadStatesParam.leftNs + threadStatesParam.recordStartNs && + e.ts + e.dur > threadStatesParam.leftNs + threadStatesParam.recordStartNs + ) { + const ts = e.ts; + e.ts = threadStatesParam.leftNs + threadStatesParam.recordStartNs; + e.dur = ts + e.dur - (threadStatesParam.leftNs + threadStatesParam.recordStartNs); + } + if (e.ts + e.dur > threadStatesParam.rightNs + threadStatesParam.recordStartNs) { + e.dur = threadStatesParam.rightNs + threadStatesParam.recordStartNs - e.ts; + } + let arr = needDeal.get(e.pid + '_' + e.tid); + let process = Utils.PROCESS_MAP.get(e.pid); + let thread = Utils.THREAD_MAP.get(e.tid); + e.process = process == null || process.length == 0 ? '[NULL]' : process; + e.thread = thread == null || thread.length == 0 ? '[NULL]' : thread; + e.stateJX = e.state; + e.state = Utils.getEndState(e.stateJX); + sum += e.dur; + arr.push(e); } + } + // 整理running线程数据、cpu层级信息 + this.mergeFreqData(needDeal, cpuMap, dealArr, sum, threadStatesParam); + // 将频点数据放置到对应cpu层级下 + this.mergeCpuData(cpuMap, needDeal); + // 将cpu层级数据放置到线程分组下 + this.mergeThreadData(threadArr, cpuMap); + // 将线程层级数据放置到进程级分组下 + this.mergePidData(pidArr, threadArr); + // 百分比保留两位小数 + this.fixedDeal(pidArr); + this.threadStatesTblSource = pidArr; + this.threadStatesTbl!.recycleDataSource = pidArr; + this.threadStatesTbl!.loading = false; + this.theadClick(pidArr); + } else { + this.threadStatesTblSource = []; + this.threadStatesTbl!.recycleDataSource = []; + this.threadStatesTbl!.loading = false; } - resultList[i].ts = resultList[i].ts - threadStatesParam.recordStartNs; - } - resultList.sort((a, b) => b.count - a.count); - return resultList; - } + }); + }); + } + ); + } - /** - * 将整理好的running频点数据通过map的键放到对应的cpu分组层级下 - */ - mergeCpuData(cpuMap: Map>, needDeal: Map>): void { - cpuMap.forEach((value: Array, key: string) => { - let arr = needDeal.get(key); - for (let i = 0; i < value.length; i++) { - for (let j = 0; j < arr!.length; j++) { - if (arr![j].cpu === value[i].cpu) { - value[i].children?.push(arr![j]); - value[i].count += arr![j].count; - value[i].dur += arr![j].dur; - value[i].percent += arr![j].percent; - } - } + private theadClick(data: Array) { + let labels = this.threadStatesTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); + if (labels) { + for (let i = 0; i < labels.length; i++) { + let label = labels[i].innerHTML; + labels[i].addEventListener('click', (e) => { + if (label.includes('Process') && i === 0) { + this.threadStatesTbl!.setStatus(data, false); + this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); + } else if (label.includes('Thread') && i === 1) { + for (let item of data) { + item.status = true; + if (item.children != undefined && item.children.length > 0) { + this.threadStatesTbl!.setStatus(item.children, false); + } } + this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); + } else if (label.includes('CPU') && i === 2) { + this.threadStatesTbl!.setStatus(data, true); + this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); + } }); + } } - - /** - * 将整理好的cpu层级数据放到对应的线程下 - */ - mergeThreadData(threadArr: Array, cpuMap: Map>): void { - for (let i = 0; i < threadArr.length; i++) { - let cpuMapData = cpuMap.get(threadArr[i].pid + '_' + threadArr[i].tid); - for (let j = 0; j < cpuMapData!.length; j++) { - threadArr[i].children.push(cpuMapData![j]); - threadArr[i].count += cpuMapData![j].count; - threadArr[i].dur += cpuMapData![j].dur; - threadArr[i].percent += cpuMapData![j].percent; - } + } + mergeFreqData(needDeal: any, cpuMap: any, dealArr: any, sum: number, threadStatesParam: SelectionParam | any) { + needDeal.forEach((value: any, key: any) => { + let resultList = new Array(); + cpuMap.set(key, new Array()); + let cpuArr = new Array(); + const multiple = 1000; + for (let i = 0; i < value.length; i++) { + if (!cpuArr.includes(value[i].cpu)) { + cpuArr.push(value[i].cpu); + cpuMap + .get(key) + .push({ + process: + Utils.PROCESS_MAP.get(value[i].pid) == null + ? 'Process ' + value[i].pid + : Utils.PROCESS_MAP.get(value[i].pid) + ' ' + value[i].pid, + thread: value[i].tid + '_' + Utils.THREAD_MAP.get(value[i].tid), + pid: value[i].pid, + tid: value[i].tid, + count: 0, + cpu: value[i].cpu, + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); } - } - - /** - * 将整理好的线程层级数据放到对应的进程下 - */ - mergePidData(pidArr: Array, threadArr: Array): void { - for (let i = 0; i < pidArr.length; i++) { - for (let j = 0; j < threadArr.length; j++) { - if (pidArr[i].pid === threadArr[j].pid) { - pidArr[i].children.push(threadArr[j]); - pidArr[i].count += threadArr[j].count; - pidArr[i].dur += threadArr[j].dur; - pidArr[i].percent += threadArr[j].percent; + for (let j = 0; j < dealArr.length; j++) { + if (value[i].cpu == dealArr[j].cpu) { + if (value[i].ts > dealArr[j].startNS) { + if (value[i].ts < dealArr[j].startNS + dealArr[j].dur) { + if (value[i].dur < dealArr[j].startNS + dealArr[j].dur - value[i].ts) { + resultList.push({ + thread: value[i].tid + '_' + value[i].thread, + count: (dealArr[j].value * value[i].dur) / multiple, + cpu: value[i].cpu, + freq: dealArr[j].value, + dur: value[i].dur, + percent: (value[i].dur / sum) * 100, + state: 'Running', + ts: value[i].ts, + }); + break; + } else { + resultList.push({ + thread: value[i].tid + '_' + value[i].thread, + count: (dealArr[j].value * (dealArr[j].startNS + dealArr[j].dur - value[i].ts)) / multiple, + cpu: value[i].cpu, + freq: dealArr[j].value, + dur: dealArr[j].startNS + dealArr[j].dur - value[i].ts, + percent: ((dealArr[j].startNS + dealArr[j].dur - value[i].ts) / sum) * 100, + state: 'Running', + ts: value[i].ts, + }); } - } - } - } - - /** - * 递归整理数据小数位 - */ - fixedDeal(arr: Array): void { - if (arr == undefined) { - return; - } - for (let i = 0; i < arr.length; i++) { - arr[i].percent = arr[i].percent > 100 ? 100 : arr[i].percent; - arr[i].percent = arr[i].percent.toFixed(2); - arr[i].dur = (arr[i].dur / 1000000).toFixed(3); - arr[i].count = (arr[i].count / 1000000).toFixed(3); - if (arr[i].freq !== '') { - if (arr[i].freq === 'unknown') { - arr[i].freq = 'unknown'; + } + } else { + if (value[i].ts + value[i].dur > dealArr[j].startNS) { + if (value[i].dur + value[i].ts - dealArr[j].startNS < dealArr[j].dur) { + resultList.push({ + thread: value[i].tid + '_' + value[i].thread, + count: (dealArr[j].value * (value[i].dur + value[i].ts - dealArr[j].startNS)) / multiple, + cpu: value[i].cpu, + freq: dealArr[j].value, + dur: value[i].dur + value[i].ts - dealArr[j].startNS, + percent: ((value[i].dur + value[i].ts - dealArr[j].startNS) / sum) * 100, + state: 'Running', + ts: dealArr[j].startNS, + }); + break; } else { - arr[i].freq = arr[i].freq / 1000; + resultList.push({ + thread: value[i].tid + '_' + value[i].thread, + count: (dealArr[j].value * dealArr[j].dur) / multiple, + cpu: value[i].cpu, + freq: dealArr[j].value, + dur: dealArr[j].dur, + percent: (dealArr[j].dur / sum) * 100, + state: 'Running', + ts: dealArr[j].startNS, + }); } + } else { + resultList.push({ + thread: value[i].tid + '_' + value[i].thread, + count: 0, + cpu: value[i].cpu, + freq: 'unknown', + dur: value[i].dur, + percent: (value[i].dur / sum) * 100, + state: 'Running', + ts: value[i].ts, + }); + break; + } } - this.fixedDeal(arr[i].children); + } + } + } + //合并同一线程内,当运行所在cpu和频点相同时,dur及percent进行累加求和,或许可以进行算法优化 + for (let i = 0; i < resultList.length; i++) { + for (let j = i + 1; j < resultList.length; j++) { + if (resultList[i].cpu == resultList[j].cpu && resultList[i].freq == resultList[j].freq) { + resultList[i].dur += resultList[j].dur; + resultList[i].percent += resultList[j].percent; + resultList[i].count += resultList[j].count; + resultList.splice(j, 1); + j--; + } + } + resultList[i].ts = resultList[i].ts - threadStatesParam.recordStartNs; + } + resultList.sort((a, b) => b.count - a.count); + cpuMap.get(key).sort((a: any, b: any) => a.cpu - b.cpu); + needDeal.set(key, resultList); + }); + } + mergeCpuData(cpuMap: any, needDeal: any) { + cpuMap.forEach((value: any, key: any) => { + let arr = needDeal.get(key); + for (let i = 0; i < value.length; i++) { + for (let j = 0; j < arr.length; j++) { + if (arr[j].cpu == value[i].cpu) { + value[i].children.push(arr[j]); + value[i].count += arr[j].count; + value[i].dur += arr[j].dur; + value[i].percent += arr[j].percent; + } } + } + }); + } + mergeThreadData(threadArr: any, cpuMap: any) { + for (let i = 0; i < threadArr.length; i++) { + let cpuMapData = cpuMap.get(threadArr[i].pid + '_' + threadArr[i].tid); + for (let j = 0; j < cpuMapData.length; j++) { + threadArr[i].children.push(cpuMapData[j]); + threadArr[i].count += cpuMapData[j].count; + threadArr[i].dur += cpuMapData[j].dur; + threadArr[i].percent += cpuMapData[j].percent; + } } - /** - * 表头点击事件 - */ - private theadClick(data: Array): void { - let labels = this.threadStatesTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - if (label.includes('Process') && i === 0) { - this.threadStatesTbl!.setStatus(data, false); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Thread') && i === 1) { - for (let item of data) { - item.status = true; - if (item.children != undefined && item.children.length > 0) { - this.threadStatesTbl!.setStatus(item.children, false); - } - } - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('CPU') && i === 2) { - this.threadStatesTbl!.setStatus(data, true); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); - } - }); - } + } + mergePidData(pidArr: any, threadArr: any) { + for (let i = 0; i < pidArr.length; i++) { + for (let j = 0; j < threadArr.length; j++) { + if (pidArr[i].pid == threadArr[j].pid) { + pidArr[i].children.push(threadArr[j]); + pidArr[i].count += threadArr[j].count; + pidArr[i].dur += threadArr[j].dur; + pidArr[i].percent += threadArr[j].percent; } + } } - initElements(): void { - this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-running-percent'); + } + fixedDeal(arr: any) { + if (arr == undefined) { + return; } - connectedCallback(): void { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.threadStatesTbl!); + for (let i = 0; i < arr.length; i++) { + arr[i].percent = arr[i].percent > 100 ? 100 : arr[i].percent; + arr[i].percent = arr[i].percent.toFixed(2); + this.fixedDeal(arr[i].children); } - initHtml(): string { - return ` + } + initElements(): void { + this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-running-percent'); + } + connectedCallback() { + super.connectedCallback(); + resizeObserver(this.parentElement!, this.threadStatesTbl!); + } + initHtml(): string { + return ` -
    - - -
    - - -
    -
    - - - - - - - - - - - - - - - ` - } - - private validationFun(threadIdValue: string, threadFuncName: string, originalThreadIdStyle: string, originalThreadFuncStyle: string, originalThreadIdPlaceholder: string, originalThreadFuncPlaceholder: string, fun: string) { - if (threadIdValue == '') { - this.threadStatesTbl!.loading = false; - this._threadId!.style.border = '1px solid rgb(255,0,0)'; - this._threadId!.setAttribute('placeholder', 'Please input thread id'); - this.threadStatesTbl!.recycleDataSource = []; - } else if (threadFuncName == '') { - this.threadStatesTbl!.loading = false; - this._threadFunc!.style.border = '1px solid rgb(255,0,0)'; - this._threadFunc!.setAttribute('placeholder', 'Please input function name'); - this.threadStatesTbl!.recycleDataSource = []; - } else { - this._threadId!.style.border = originalThreadIdStyle; - this._threadFunc!.style.border = originalThreadFuncStyle; - this._threadId!.setAttribute('placeholder', originalThreadIdPlaceholder); - this._threadFunc!.setAttribute('placeholder', originalThreadFuncPlaceholder); - if (fun == 'single') { - getGpufreqDataCut(threadIdValue, threadFuncName, this.currentSelectionParam.leftNs, this.currentSelectionParam.rightNs, true, false).then((result) => { - let _initData = JSON.parse(JSON.stringify(this.initData)) - this.dataCutFun(_initData, result) - }) - } - if (fun == 'loop') { - getGpufreqDataCut(threadIdValue, threadFuncName, this.currentSelectionParam.leftNs, this.currentSelectionParam.rightNs, false, true).then((result) => { - let _initData = JSON.parse(JSON.stringify(this.initData)) - this.dataCutFun(_initData, result) - }) - } - - } - } - - private dataCutFun(initData: Array, dataCut: Array) { - let earliest: number = 0 - let selectGpufreqData = new Array(); - if (initData.length > 0 && dataCut.length > 0) { - let lastList = [] - getGpufreqData(this.currentSelectionParam.leftNs, this.currentSelectionParam.rightNs, true).then((result) => { - if (result.length > 0) { - earliest = result[0].startNS - let _dataCut = dataCut.filter(i => i.startTime >= earliest); - for (let i = 0; i < _dataCut.length; i++) { - let e = _dataCut[i]; - for (let j of initData) { - if (e.startTime >= j.startNS && e.startTime <= j.endTime) { - if (e.endTime <= j.endTime) { - let obj = { - 'startNS': e.startTime, - 'endTime': e.endTime, - 'dur': e.endTime - e.startTime, - 'count': (e.endTime - e.startTime) * j.value, - 'ts': e.startTime + this.currentSelectionParam.recordStartNs, - 'parentIndex': i, - 'thread': j.thread, - 'filterId': j.filterId, - 'freq': j.freq, - 'value': j.value - } - lastList.push(obj) - } else { - let obj = { - 'startNS': e.startTime, - 'endTime': j.endTime, - 'dur': j.endTime - e.startTime, - 'count': (j.endTime - e.startTime) * j.value, - 'ts': e.startTime + this.currentSelectionParam.recordStartNs, - 'parentIndex': i, - 'thread': j.thread, - 'filterId': j.filterId, - 'freq': j.freq, - 'value': j.value - } - lastList.push(obj) - } - } else if (e.startTime <= j.startNS && j.endTime <= e.endTime) { - let obj = { - 'startNS': j.startNS, - 'endTime': j.endTime, - 'dur': j.endTime - j.startNS, - 'count': (j.endTime - j.startNS) * j.value, - 'ts': j.startNS + this.currentSelectionParam.recordStartNs, - 'parentIndex': i, - 'thread': j.thread, - 'filterId': j.filterId, - 'freq': j.freq, - 'value': j.value - } - lastList.push(obj) - } - else if (j.startNS <= e.endTime && e.endTime <= j.endTime) { - let obj = { - 'startNS': j.startNS, - 'endTime': e.endTime, - 'dur': e.endTime - j.startNS, - 'count': (e.endTime - j.startNS) * j.value, - 'ts': j.startNS + this.currentSelectionParam.recordStartNs, - 'parentIndex': i, - 'thread': j.thread, - 'filterId': j.filterId, - 'freq': j.freq, - 'value': j.value - } - lastList.push(obj) - } - } - } - let tree = this.createTree(lastList) - selectGpufreqData.push(tree) - this.threadStatesTbl!.recycleDataSource = selectGpufreqData; - this.threadStatesTbl!.loading = false; - this.theadClick(selectGpufreqData) - } else { - this.threadStatesTbl!.recycleDataSource = [] - this.threadStatesTbl!.loading = false; - } - - }) - - - } else { - this.threadStatesTbl!.recycleDataSource = [] - this.threadStatesTbl!.loading = false; - } - } - - private createTree(data: Array) { - if (data.length > 0) { - const root = { - thread: "gpufreq Frequency", - count: '0', - freq: '', - dur: '0', - percent: '100', - level: 1, - children: [], - }; - - const valueMap = {}; - data.forEach((item: any) => { - const parentIndex = item.parentIndex; - const freq = item.freq; - const unit = 1000000 - const kunit= 1000000000000 - item.thread = `${item.thread} Frequency`; - item.level = 4 - item.dur = (item.dur / unit).toFixed(3) - item.count = (item.count / kunit).toFixed(3) - item.freq = (item.freq).toFixed(3) - if (!valueMap[parentIndex]) { - valueMap[parentIndex] = { - thread: `cycle ${parentIndex + 1} ${item.thread}`, - count: item.count, - dur: item.dur, - ts: item.ts, - startTime: (item.startNS / unit).toFixed(3), - startNS: item.startNS, - percent: '100', - level: 2, - cycle: parentIndex + 1, - children: [], - }; - } else { - let fdur = Number(valueMap[parentIndex].dur) - let fcount = Number(valueMap[parentIndex].count) - let idur = Number(item.dur) - let icount = Number(item.count) - fdur += idur; - valueMap[parentIndex].dur = fdur.toFixed(3); - fcount += icount; - valueMap[parentIndex].count = fcount.toFixed(3); - } - - if (!valueMap[parentIndex].children[freq]) { - valueMap[parentIndex].children[freq] = { - thread: item.thread, - count: item.count, - gpufreq: item.freq, - dur: item.dur, - percent: '100', - level: 3, - children: [], - }; - } else { - let zdur = Number(valueMap[parentIndex].children[freq].dur) - let zcount = Number(valueMap[parentIndex].children[freq].count) - let idur = Number(item.dur) - let icount = Number(item.count) - zdur += idur; - valueMap[parentIndex].children[freq].dur = zdur.toFixed(3); - zcount += icount; - valueMap[parentIndex].children[freq].count = zcount.toFixed(3); - } - valueMap[parentIndex].children[freq].children.push(item); - - }) - Object.values(valueMap).forEach((node: any) => { - const parentNode = valueMap[node.value - 1]; - if (parentNode) { - parentNode.children.push(node); - let pdur = Number(parentNode.dur) - let pcount = Number(parentNode.count) - let ndur = Number(node.dur) - let ncount = Number(node.count) - pdur += ndur; - parentNode.dur = pdur.toFixed(3); - pcount += ncount; - parentNode.count += pcount.toFixed(3); - } else { - root.children.push(node); - let rdur = Number(root.dur) - let rcount = Number(root.count) - let ndur = Number(node.dur) - let ncount = Number(node.count) - rdur += ndur; - root.dur = rdur.toFixed(3); - rcount += ncount; - root.count = rcount.toFixed(3); - } - - }); - // 移除 key 值 - root.children.forEach((item: any) => { - item.children = Object.values(item.children); - }) - function calculatePercent(node: any) { - if (node.count === 0 || node.count === undefined) { - return; - } - node.percent = (Number(node.count) / Number(root.count) * 100).toFixed(2); - - if (node.children && node.children.length > 0) { - node.children.forEach(calculatePercent); - } else { - return; - } - } - calculatePercent(root); - - SegMenTaTion.setChartData('GPU-FREQ', root.children) - return root; - - } else { - return {} - } - } - - private theadClick(data: Array) { - let labels = this.threadStatesTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - - if (label.includes('All') && i === 0) { - this.threadStatesTbl!.setStatus(data, false); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - - } else if (label.includes('Cycle') && i === 1) { - for (let item of data) { - item.status = true; - if (item.children != undefined && item.children.length > 0) { - this.threadStatesTbl!.setStatus(item.children, false); - } - } - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - - } else if (label.includes('Freq') && i === 2) { - for (let item of data) { - item.status = true; - for (let e of item.children ? item.children : []) { - e.status = true; - if (e.children != undefined && e.children.length > 0) { - this.threadStatesTbl!.setStatus(e.children, false, 0); - } - } - } - - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - - } else if (label.includes('Thread') && i === 3) { - this.threadStatesTbl!.setStatus(data, true); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); - - } - }); - } - } - - } - -} \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/gpufreq/tabPaneGpufreqUsage.ts b/ide/src/trace/component/trace/sheet/gpufreq/tabPaneGpufreqUsage.ts deleted file mode 100644 index eac6a1339..000000000 --- a/ide/src/trace/component/trace/sheet/gpufreq/tabPaneGpufreqUsage.ts +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getGpufreqData } from '../../../../database/SqlLite.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { SliceGroup } from '../../../../bean/StateProcessThread.js'; - -@element('tabpane-gpufreq') -export class TabPaneGpufreq extends BaseElement { - private threadStatesTbl: LitTable | null | undefined; - private currentSelectionParam: Selection | undefined; - - set data(clockCounterValue: SelectionParam | any) { - let dataSource: Array = []; - if (this.currentSelectionParam === clockCounterValue) { - return; - } - this.currentSelectionParam = clockCounterValue; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = true; - getGpufreqData(clockCounterValue.leftNs, clockCounterValue.rightNs, false).then((result) => { - if (result != null && result.length > 0) { - let resultList = JSON.parse(JSON.stringify(result)) - if (result.length == 1) { - resultList[0].dur = clockCounterValue.rightNs - clockCounterValue.leftNs - resultList[0].count = resultList[0].dur * resultList[0].value - } else { - resultList[0].dur = resultList[1].startNS - clockCounterValue.leftNs - resultList[0].count = resultList[0].dur * resultList[0].value - - resultList[resultList.length - 1].dur = clockCounterValue.rightNs - resultList[resultList.length - 1].startNS - resultList[resultList.length - 1].count = resultList[resultList.length - 1].dur * resultList[resultList.length - 1].value - } - let sd: any = this.createTree(resultList); - dataSource = sd; - this.threadStatesTbl!.recycleDataSource = dataSource; - this.threadStatesTbl!.loading = false; - let List = new Array(); - List.push(...dataSource) - this.theadClick(List) - } else { - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - } - - }) - - } - - initElements(): void { - this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-gpufreq-percent'); - } - - connectedCallback() { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.threadStatesTbl!); - } - - initHtml(): string { - return ` - - - - - - - - - - - - - - ` - } - - private createTree(sourceList: Array) { - let selectGpufreqData = new Array(); - if (sourceList.length > 0) { - function createTree(data: Array) { - const root = { - thread: "gpufreq Frequency", - count: '0', - freq: '', - dur: '0', - percent: '100', - children: [], - }; - - const valueMap = {}; - data.forEach((item: any) => { - const freq = item.freq; - const unit = 1000000 - const kunit= 1000000000000 - item.dur = (item.dur / unit).toFixed(3) - item.count = (item.count / kunit).toFixed(3) - item.freq = (item.freq).toFixed(3) - item.thread = `${item.thread} Frequency` - if (!valueMap[freq]) { - valueMap[freq] = { - thread: "gpufreq Frequency", - count: item.count, - gpufreq: item.freq, - dur: item.dur, - percent: '100', - children: [], - }; - } else { - let fdur = Number(valueMap[freq].dur) - let fcount = Number(valueMap[freq].count) - let idur = Number(item.dur) - let icount = Number(item.count) - fdur += idur; - valueMap[freq].dur = fdur.toFixed(3); - fcount += icount; - valueMap[freq].count = fcount.toFixed(3); - } - valueMap[freq].children.push(item); - }); - - function calculatePercent(node: any) { - if (node.count === 0 || node.count === undefined) { - return; - } - node.percent = (Number(node.count) / Number(root.count) * 100).toFixed(2); - - if (node.children && node.children.length > 0) { - node.children.forEach(calculatePercent); - } else { - return - } - } - - Object.values(valueMap).forEach((node: any) => { - const parentNode = valueMap[node.value - 1]; - if (parentNode) { - parentNode.children.push(node); - let pdur = Number(parentNode.dur) - let pcount = Number(parentNode.count) - let ndur = Number(node.dur) - let ncount = Number(node.count) - pdur += ndur; - parentNode.dur = pdur.toFixed(3); - pcount += ncount; - parentNode.count += pcount.toFixed(3); - } else { - root.children.push(node); - let rdur = Number(root.dur) - let rcount = Number(root.count) - let ndur = Number(node.dur) - let ncount = Number(node.count) - rdur += ndur; - root.dur = rdur.toFixed(3); - rcount += ncount; - root.count = rcount.toFixed(3); - } - - }); - calculatePercent(root); - - return root; - } - const tree = createTree(sourceList); - selectGpufreqData.push(tree) - - } - return selectGpufreqData - } - - private theadClick(data: Array) { - let labels = this.threadStatesTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - - if (label.includes('All') && i === 0) { - this.threadStatesTbl!.setStatus(data, false); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - - } else if (label.includes('Freq') && i === 1) { - - for (let item of data) { - item.status = true; - if (item.children != undefined && item.children.length > 0) { - this.threadStatesTbl!.setStatus(item.children, false); - } - } - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - - } else if (label.includes('Thread') && i === 2) { - this.threadStatesTbl!.setStatus(data, true); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); - } - }); - } - } - } -} \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/schedswitch/TabPaneSchedSwitch.ts b/ide/src/trace/component/trace/sheet/schedswitch/TabPaneSchedSwitch.ts deleted file mode 100644 index 6436ad996..000000000 --- a/ide/src/trace/component/trace/sheet/schedswitch/TabPaneSchedSwitch.ts +++ /dev/null @@ -1,736 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { log } from 'console'; -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitButton } from '../../../../../base-ui/button/LitButton.js'; -import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; -import { querySchedThreadStates, querySingleCutData, queryLoopCutData } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { LitChartColumn } from '../../../../../base-ui/chart/column/LitChartColumn.js'; -import { TableNoData } from '../../../schedulingAnalysis/TableNoData.js'; -import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { SchedSwitchStack, schedThreadInitData } from '../../../../bean/SchedSwitchStruet.js'; -import { SegMenTaTion } from '../../../../../trace/component/chart/SpSegmentationChart.js' - - -@element('tabpane-schedswitch') -export class TabPaneSchedSwitch extends BaseElement { - private schedSwitchTbl: LitTable | null | undefined; - private threadQueryDIV: Element | null | undefined; - private rightDIV: HTMLDivElement | null | undefined; - private threadIdInput: HTMLInputElement | null | undefined; - private funcNameInput: HTMLInputElement | null | undefined; - private singleBtn: LitButton | null | undefined; - private loopBtn: LitButton | null | undefined; - private cycleALeftInput: HTMLInputElement | null | undefined; - private cycleARightInput: HTMLInputElement | null | undefined; - private cycleBLeftInput: HTMLInputElement | null | undefined; - private cycleBRightInput: HTMLInputElement | null | undefined; - private queryButton: LitButton | null | undefined; - private threadFlag: string = ''; - private selectionParam: SelectionParam | undefined; - private canvansName: HTMLDivElement | null | undefined; - private singleSourceData: Array = []; - private loopSourceData: Array = []; - private chartTotal: LitChartColumn | null | undefined; - private histogramSource: Array = []; - private rangeA: object = {}; - private rangeB: object = {}; - private rangeTotal: object = {}; - private clickThreadChildren: Array = []; - private isThreadStatesData: boolean = false; - private clickHighlightCondition: string = ''; - - - set data(threadStatesParam: SelectionParam | any) { - if (this.selectionParam === threadStatesParam) return; - let tblVal: any = this.schedSwitchTbl; - let threadIdInput: any = this.threadIdInput; - let funcNameInput: any = this.funcNameInput; - this.schedSwitchTbl!.recycleDataSource = []; - this.queryButton!.style.pointerEvents = 'none'; - this.schedSwitchTbl!.loading = false; - this.isThreadStatesData = false; - tblVal.value = []; - threadIdInput.value = ''; - funcNameInput.value = ''; - funcNameInput.style.border = '1px solid rgb(151,151,151)'; - threadIdInput.style.border = '1px solid rgb(151,151,151)'; - this.selectionParam = threadStatesParam; - this.canvansName!.textContent = 'sched switch平均分布图'; - this.isQueryButtonClick(false); - this.isSingleButtonFn(false); - this.isLoopButtonFn(false); - this.isCanvansDisplayFn(false); - } - initElements(): void { - this.schedSwitchTbl = this.shadowRoot!.querySelector('#tb-running'); - this.threadQueryDIV = this.shadowRoot?.querySelector('#data-cut'); - this.rightDIV = this.shadowRoot?.querySelector('#right'); - this.canvansName = this.shadowRoot!.querySelector('.sched-subheading'); - this.chartTotal = this.shadowRoot!.querySelector('#chart_total'); - this.threadIdInput = this.shadowRoot?.getElementById('cut-threadid') as HTMLInputElement; - this.funcNameInput = this.shadowRoot?.querySelector('#cut-thread-func') as HTMLInputElement; - this.singleBtn = this.shadowRoot?.querySelector('.single-btn'); - this.loopBtn = this.shadowRoot?.querySelector('.loop-btn'); - this.cycleALeftInput = this.shadowRoot?.getElementById('leftA') as HTMLInputElement; - this.cycleARightInput = this.shadowRoot?.getElementById('rightA') as HTMLInputElement; - this.cycleBLeftInput = this.shadowRoot?.getElementById('leftB') as HTMLInputElement; - this.cycleBRightInput = this.shadowRoot?.getElementById('rightB') as HTMLInputElement; - this.queryButton = this.shadowRoot?.querySelector('.query-btn'); - this.singleBtn?.addEventListener('click', (e) => { this.queryCutInfoFn(this.singleBtn!.innerHTML) }); - this.loopBtn?.addEventListener('click', (e) => { this.queryCutInfoFn(this.loopBtn!.innerHTML) }); - this.queryButton!.addEventListener('click', (e) => { this.queryCycleRangeData() }); - this.schedSwitchTbl!.addEventListener('row-click', (evt: any) => { - let data = evt.detail.data as SchedSwitchStack; - if (data.level == 'process') { - this.isCanvansDisplayFn(false); - this.threadFlag = ''; - } else if (data.level == 'thread') { - this.cycleALeftInput!.value = ''; - this.cycleARightInput!.value = ''; - this.cycleBLeftInput!.value = ''; - this.cycleBRightInput!.value = ''; - this.histogramSource = []; - this.clickThreadChildren = data.children; - this.queryButton!.style.pointerEvents = 'none'; - this.isCanvansDisplayFn(true); - this.isQueryButtonClick(false); - this.threadFlag = 'thread'; - this.clickHighlightCondition = `${data.process} - ${data.pid} - ${data.thread} - ${data.tid}`; - this.rangeTotal = { - count: evt.detail.count, - cycleNum: evt.detail.cycleNum, - average: evt.detail.cycleNum ? Math.ceil(evt.detail.count / evt.detail.cycleNum) : 0, - size: 'Total', - isHover: false, - color: '#2f72f8' - }; - this.histogramSource.push(this.rangeTotal); - data.isSelected = true; - this.schedSwitchTbl!.clearAllSelection(data); - this.schedSwitchTbl!.setCurrentSelection(data); - // SegMenTaTion.setChartData('SCHED-SWITCH', evt.detail.children); - this.queryHistogramData() - } else if (data.level == 'cycle') { - if (this.threadFlag == 'thread') { - this.isCanvansDisplayFn(true); - } - if (this.clickHighlightCondition == `${data.process} - ${data.pid} - ${data.thread} - ${data.tid}`) { - data.isSelected = true; - this.schedSwitchTbl!.clearAllSelection(data); - this.schedSwitchTbl!.setCurrentSelection(data); - // SegMenTaTion.tabHover('SCHED-SWITCH', true, data!.cycle); - } - } - }) - this.cycleALeftInput!.addEventListener('input', (evt: any) => { - this.checkInputRangeFn(this.cycleALeftInput, this.cycleARightInput, this.cycleBLeftInput, this.cycleBRightInput, this.cycleALeftInput!.value, this.cycleARightInput!.value) - }) - this.cycleARightInput!.addEventListener('input', (evt: any) => { - this.checkInputRangeFn(this.cycleARightInput, this.cycleALeftInput, this.cycleBLeftInput, this.cycleBRightInput, this.cycleALeftInput!.value, this.cycleARightInput!.value) - }) - this.cycleBLeftInput!.addEventListener('input', (evt: any) => { - this.checkInputRangeFn(this.cycleBLeftInput, this.cycleBRightInput, this.cycleALeftInput, this.cycleARightInput, this.cycleBLeftInput!.value, this.cycleBRightInput!.value) - }) - this.cycleBRightInput!.addEventListener('input', (evt: any) => { - this.checkInputRangeFn(this.cycleBRightInput, this.cycleBLeftInput, this.cycleALeftInput, this.cycleARightInput, this.cycleBLeftInput!.value, this.cycleBRightInput!.value) - }) - } - - checkInputRangeFn(firstInput: any, secondInput: any, thirdInput: any, fourInput: any, lVal: string, rVal: string): void { - let leftVal = Number(lVal); - let rightVal = Number(rVal); - if (firstInput!.value != '' && secondInput!.value != '') { - if (firstInput!.value != '' && secondInput!.value != '') { - if (leftVal >= rightVal) { - firstInput!.style.color = 'red'; - this.queryButton!.style.pointerEvents = 'none'; - this.isQueryButtonClick(false); - } else if (leftVal < rightVal) { - firstInput!.style.color = 'black'; - secondInput!.style.color = 'black'; - this.queryButton!.style.pointerEvents = 'auto'; - this.isQueryButtonClick(true); - } - } - } else if ((firstInput.value == '' && secondInput!.value != '') || (firstInput!.value != '' && secondInput!.value == '')) { - this.queryButton!.style.pointerEvents = 'none'; - this.isQueryButtonClick(false); - } else if (firstInput!.value == '' && secondInput!.value == '' && thirdInput!.value != '' && fourInput!.value != '') { - this.queryButton!.style.pointerEvents = 'auto'; - this.isQueryButtonClick(true); - } - } - - async initThreadStateData(threadParam: SelectionParam | null | undefined): Promise { - let leftStartNs = threadParam!.leftNs + threadParam!.recordStartNs; - let rightEndNs = threadParam!.rightNs + threadParam!.recordStartNs; - let res = await querySchedThreadStates(threadParam!.threadIds, leftStartNs, rightEndNs); - if (res.length == 0) { - this.schedSwitchTbl!.recycleDataSource = []; - this.schedSwitchTbl!.loading = false; - this.clickTreeTitleFn(this.schedSwitchTbl!.recycleDataSource); - return - } - this.singleSourceData = JSON.parse(JSON.stringify(res)); - this.loopSourceData = JSON.parse(JSON.stringify(res)); - this.isThreadStatesData = true; - } - - async queryCutInfoFn(btnHtml: string): Promise { - let threadId = this.threadIdInput!.value.trim(); - let threadFunName = this.funcNameInput!.value.trim(); - let leftStartNs = this.selectionParam!.leftNs + this.selectionParam!.recordStartNs; - let rightEndNs = this.selectionParam!.rightNs + this.selectionParam!.recordStartNs; - let cutData: Array = []; - let tblVal: any = this.schedSwitchTbl; - this.threadFlag = ''; - if (threadId != "" && threadFunName != "") { - this.threadIdInput!.style.border = '1px solid rgb(151,151,151)'; - this.funcNameInput!.style.border = '1px solid rgb(151,151,151)'; - tblVal!.value = []; - this.isCanvansDisplayFn(false); - this.schedSwitchTbl!.loading = true; - if (!this.isThreadStatesData) this.initThreadStateData(this.selectionParam); - if (btnHtml == 'Single') { - this.isSingleButtonFn(true); - this.isLoopButtonFn(false); - let res = await querySingleCutData(threadFunName, threadId, leftStartNs, rightEndNs); - if (res.length == 0) { - this.schedSwitchTbl!.recycleDataSource = []; - this.schedSwitchTbl!.loading = false; - this.clickTreeTitleFn(this.schedSwitchTbl!.recycleDataSource); - return - }; - for (let idx = 0; idx < res.length; idx++) { - for (let i = 0; i < this.singleSourceData.length; i++) { - let singleItem = this.singleSourceData[i] - if (!(singleItem.endTs < res[idx].cycleStartTime || singleItem.ts > res[idx].cycleEndTime)) { - let info = { - pid: singleItem.pid, - tid: singleItem.tid, - state: singleItem.state, - cycleStartTime: res[idx].cycleStartTime, - cycleEndTime: res[idx].cycleEndTime, - name: res[idx].name, - funId: res[idx].id, - runningCnt: singleItem.state == 'Running' ? 1 : 0, - } - cutData.push(info) - } - } - } - }; - if (btnHtml == 'Loop') { - this.isLoopButtonFn(true); - this.isSingleButtonFn(false); - this.schedSwitchTbl!.loading = true; - let res = await queryLoopCutData(threadFunName, threadId, leftStartNs, rightEndNs); - if (res.length == 0) { - this.schedSwitchTbl!.recycleDataSource = []; - this.schedSwitchTbl!.loading = false; - this.clickTreeTitleFn(this.schedSwitchTbl!.recycleDataSource); - return - }; - for (let idx = 0; idx < res.length - 1; idx++) { - res[idx].cycleEndTime = res[idx + 1].cycleStartTime; - for (let i = 0; i < this.loopSourceData.length; i++) { - let loopItem = this.loopSourceData[i] - if (!(loopItem.endTs < res[idx].cycleStartTime || loopItem.ts > res[idx].cycleEndTime)) { - let info = { - pid: loopItem.pid, - tid: loopItem.tid, - state: loopItem.state, - cycleStartTime: res[idx].cycleStartTime, - cycleEndTime: res[idx + 1].cycleStartTime, - name: res[idx].name, - funId: res[idx].id, - runningCnt: loopItem.state == 'Running' ? 1 : 0, - } - cutData.push(info) - } - } - } - }; - this.handleSchedThreadData(cutData) - } else { - if (threadId == "") { - this.threadIdInput!.style.border = '2px solid rgb(255,0,0)'; - this.threadIdInput!.setAttribute('placeholder', 'Please input thread id'); - } else { - this.threadIdInput!.style.border = '1px solid rgb(151,151,151)'; - }; - if (threadFunName == '') { - this.funcNameInput!.style.border = '2px solid rgb(255,0,0)'; - this.funcNameInput!.setAttribute('placeholder', 'Please input function name'); - } else { - this.funcNameInput!.style.border = '1px solid rgb(151,151,151)'; - } - } - } - - handleSchedThreadData(result: Array): void { - let resultData: Array = []; - if (result != null && result.length > 0) { - for (let e of result) { - if (this.selectionParam!.processIds.includes(e.pid)) { - let process = Utils.PROCESS_MAP.get(e.pid); - let thread = Utils.THREAD_MAP.get(e.tid); - e.process = process == null || process.length == 0 ? '[NULL]' : process; - e.thread = thread == null || thread.length == 0 ? '[NULL]' : thread; - e.dur = e.cycleEndTime - e.cycleStartTime; - e.leftNS = e.cycleStartTime - this.selectionParam!.recordStartNs; - resultData.push(e); - } - } - this.translateIntoTreeData(resultData); - } - } - - translateIntoTreeData(data: Array): void { - let group: any = {}; - if (data != null && data.length > 0) { - data.forEach((slice: any) => { - let item = { - title: `${slice.thread}`, - count: slice.runningCnt, - cycleNum: 1, - state: slice.state, - tid: slice.tid, - pid: slice.pid, - thread: slice.thread, - process: slice.process, - cycleStartTime: slice.leftNS, - duration: slice.dur, - level: 'cycle', - }; - if (group[`${slice.pid}`]) { - let process = group[`${slice.pid}`]; - process.count += slice.runningCnt; - let thread = process.children.find((child: any) => child.title === `${slice.thread}` + `[${slice.tid}]`); - if (thread) { - thread.count += slice.runningCnt; - let cycle = thread.children.find((child: any) => child.cycleStartTime === slice.leftNS); - if (cycle) { - cycle.count += slice.runningCnt; - } else { - thread.cycleNum += 1; - process.cycleNum += 1; - thread.duration += slice.dur; - process.duration += slice.dur; - thread.children.push(item); - } - } else { - process.cycleNum += 1; - process.duration += slice.dur; - process.children.push({ - title: `${slice.thread}` + `[${slice.tid}]`, - count: slice.runningCnt, - cycleNum: 1, - pid: slice.pid, - tid: slice.tid, - thread: slice.thread, - process: slice.process, - duration: slice.dur, - level: 'thread', - cycleStartTime: '', - children: [item] - }); - } - } else { - group[`${slice.pid}`] = { - title: `${slice.process}` + `[${slice.pid}]`, - count: slice.runningCnt, - cycleNum: 1, - tid: slice.tid, - pid: slice.pid, - thread: slice.thread, - process: slice.process, - duration: slice.dur, - level: 'process', - cycleStartTime: '', - children: [ - { - title: `${slice.thread}` + `[${slice.tid}]`, - count: slice.runningCnt, - cycleNum: 1, - tid: slice.tid, - pid: slice.pid, - thread: slice.thread, - process: slice.process, - duration: slice.dur, - level: 'thread', - cycleStartTime: '', - children: [item] - }, - ], - }; - } - }); - group = Object.values(group); - for (let i = 0; i < group.length; i++) { - this.addCycleNumber([group[i]]); - } - this.schedSwitchTbl!.recycleDataSource = group; - this.schedSwitchTbl!.loading = false; - this.clickTreeTitleFn(this.schedSwitchTbl!.recycleDataSource); - } - } - addCycleNumber(groupItem: Array): void { - let flagNumber = 0; - for (let idx = 0; idx < groupItem.length; idx++) { - groupItem[idx].duration = (groupItem[idx].duration / 1000000.0).toFixed(3); - if (!(groupItem[idx].children)) { - flagNumber += 1; - groupItem[idx].cycle = flagNumber; - groupItem[idx].title = `cycle ${flagNumber}-` + groupItem[idx].title; - groupItem[idx].cycleStartTime = (groupItem[idx].cycleStartTime / 1000000.0).toFixed(3); - } else { - this.addCycleNumber(groupItem[idx].children) - } - } - } - - clickTreeTitleFn(data: Array): void { - let labelList = this.schedSwitchTbl!.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - if (labelList) { - for (let i = 0; i < labelList.length; i++) { - let lable = labelList[i].innerHTML; - labelList[i].addEventListener('click', (e) => { - if (lable.includes('Process') && i == 0) { - this.schedSwitchTbl!.setStatus(data, false); - this.schedSwitchTbl!.recycleDs = this.schedSwitchTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (lable.includes('Thread') && i == 1) { - for (let item of data) { - item.status = true; - if (item.children != undefined && item.children.length > 0) { - this.schedSwitchTbl!.setStatus(item.children, false); - } - } - this.schedSwitchTbl!.recycleDs = this.schedSwitchTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (lable.includes('Cycle') && i == 2) { - this.schedSwitchTbl!.setStatus(data, true); - this.schedSwitchTbl!.recycleDs = this.schedSwitchTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand) - } - }) - - } - } - - } - - queryCycleRangeData(): void { - let cycleALeft = this.cycleALeftInput!.value.trim(); - let cycleARight = this.cycleARightInput!.value.trim(); - let cycleBLeft = this.cycleBLeftInput!.value.trim(); - let cycleBRight = this.cycleBRightInput!.value.trim(); - this.histogramSource = []; - this.histogramSource.push(this.rangeTotal) - if (cycleALeft != '' && cycleARight != '' && cycleALeft != cycleARight) { - let countA = 0; - let rangeFilterA = this.clickThreadChildren.filter((it: any) => Number(it.duration) >= Number(cycleALeft) && Number(it.duration) < Number(cycleARight)); - rangeFilterA.forEach((item: any) => { - countA += item.count - }) - this.rangeA = { - count: countA, - cycleNum: rangeFilterA.length, - average: rangeFilterA.length ? Math.ceil(countA / rangeFilterA.length) : 0, - size: 'Cycle A', - isHover: false, - color: '#ffab67' - } - this.histogramSource.push(this.rangeA); - } - - if (cycleBLeft != '' && cycleBRight != '' && cycleBLeft != cycleBRight) { - let countB = 0; - let rangeFilterB = this.clickThreadChildren.filter((it: any) => Number(it.duration) >= Number(cycleBLeft) && Number(it.duration) < Number(cycleBRight)) - rangeFilterB.forEach((item: any) => { - countB += item.count - }) - this.rangeB = { - count: countB, - cycleNum: rangeFilterB.length, - average: rangeFilterB.length ? Math.ceil(countB / rangeFilterB.length) : 0, - size: 'Cycle B', - isHover: false, - color: '#a285d2' - } - this.histogramSource.push(this.rangeB) - } - this.queryHistogramData(); - } - - queryHistogramData(): void { - let source = []; - source = this.histogramSource.map((it: any, index: number) => { - let data: any = { - cycle: it.size, - average: it.average, - visible: 1, - color: it.color, - }; - return data; - }); - this.chartTotal!.config = { - data: source, - appendPadding: 10, - xField: 'cycle', - yField: 'average', - notSort: true, - removeUnit: true, - seriesField: '', - color: (a) => { - if (a.cycle === 'Total') { - return '#2f72f8'; - } else if (a.cycle === 'Cycle A') { - return '#ffab67'; - } else if (a.cycle === 'Cycle B') { - return '#a285d2'; - } else { - return '#0a59f7'; - } - }, - tip: (a) => { - if (a && a[0]) { - let tip = ''; - for (let obj of a) { - tip = - `${tip} -
    -
    -
    ${obj.xLabel}:${obj.obj.average}
    -
    - `; - } - return tip; - } else { - return ''; - } - }, - label: null, - }; - } - - isCanvansDisplayFn(flag: boolean): void { - if (!flag) { - this.setAttribute('isCanvansDisplay', '') - } else { - this.removeAttribute('isCanvansDisplay') - } - } - - isSingleButtonFn(flag: boolean): void { - if (flag) { - this.setAttribute('isSingleButton', '') - } else { - this.removeAttribute('isSingleButton') - } - } - - isLoopButtonFn(flag: boolean): void { - if (flag) { - this.setAttribute('isLoopButton', '') - } else { - this.removeAttribute('isLoopButton') - } - } - - isQueryButtonClick(flag: boolean): void { - if (flag) { - this.setAttribute('isQueryButton', '') - } else { - this.removeAttribute('isQueryButton') - } - } - - connectedCallback() { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.schedSwitchTbl!); - } - initHtml(): string { - return ` - -
    - - -
    - - -
    -
    -
    -
    - - - - - - - - - - -
    - - -
    - - ` - } -} diff --git a/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts b/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts index d04adca86..976bccf21 100644 --- a/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts +++ b/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts @@ -33,7 +33,7 @@ export class TabPaneFlag extends BaseElement { this.systemTrace = document .querySelector('body > sp-application') ?.shadowRoot!.querySelector('#sp-system-trace'); - this.panelTable = this.shadowRoot!.querySelector('.notes-editor-panel'); + this.panelTable = this.shadowRoot!.querySelector('.notes-editor-panel'); this.panelTable!.addEventListener('row-click', (evt: any) => { if (evt.detail.data.startTime === undefined) { return; @@ -132,7 +132,6 @@ export class TabPaneFlag extends BaseElement { */ private eventHandler(): void { let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf; - tr[0].querySelector('#text-input')!.disabled = true; tr[0].querySelector('.removeAll')!.addEventListener('click', (evt: any) => { this.systemTrace!.flagList = []; let flagList = [...this.flagList]; @@ -148,7 +147,7 @@ export class TabPaneFlag extends BaseElement { this.panelTable!.addEventListener('click', (event: any) => { if (this.flagList.length === 0) { return; - } + } for (let i = 1; i < tr.length; i++) { let inputValue = tr[i].querySelector('#text-input')!.value; if (this.tableDataSource[i].startTime === this.flagList[i - 1].time) { diff --git a/ide/src/trace/database/SqlLite.ts b/ide/src/trace/database/SqlLite.ts index 878d8f637..354e6384a 100644 --- a/ide/src/trace/database/SqlLite.ts +++ b/ide/src/trace/database/SqlLite.ts @@ -90,7 +90,6 @@ import { type SnapshotStruct } from './ui-worker/ProcedureWorkerSnapshot.js'; import { type MemoryConfig } from '../bean/MemoryConfig.js'; import { LogStruct } from './ui-worker/ProcedureWorkerLog.js'; import { HiSysEventStruct } from './ui-worker/ProcedureWorkerHiSysEvent.js'; -import { FuncNameCycle } from '../bean/BinderProcessThread.js'; class DataWorkerThread extends Worker { taskMap: any = {}; @@ -298,8 +297,8 @@ export class DbPool { } } }; - thread!.onmessageerror = (e) => { }; - thread!.onerror = (e) => { }; + thread!.onmessageerror = (e) => {}; + thread!.onerror = (e) => {}; thread!.id = i; thread!.busy = false; this.works?.push(thread!); @@ -724,8 +723,8 @@ export const getTabFps = (leftNs: number, rightNs: number): Promise> { $leftNS: leftNs, $rightNS: rightNs } ); -export const getTabCounters = (processFilterIds: Array, virtualFilterIds: Array, startTime: number) => { - let processSql = `select + export const getTabCounters = (processFilterIds: Array, virtualFilterIds: Array, startTime: number) => { + let processSql = `select t1.filter_id as trackId, t2.name, value, @@ -741,8 +740,8 @@ export const getTabCounters = (processFilterIds: Array, virtualFilterIds where filter_id in (${processFilterIds.join(',')}) and - startTime <= ${startTime}`; - let virtualSql = `select + startTime <= ${startTime}` ; + let virtualSql = `select t1.filter_id as trackId, t2.name, value, @@ -759,18 +758,18 @@ export const getTabCounters = (processFilterIds: Array, virtualFilterIds filter_id in (${virtualFilterIds.join(',')}) and startTime <= ${startTime}`; - let sql = ''; - if (processFilterIds.length > 0 && virtualFilterIds.length > 0) { - sql = `${processSql} union ${virtualSql}`; - } else { - if (processFilterIds.length > 0) { - sql = processSql; + let sql = ''; + if (processFilterIds.length > 0 && virtualFilterIds.length > 0) { + sql = `${processSql} union ${virtualSql}`; } else { - sql = virtualSql; + if (processFilterIds.length > 0) { + sql = processSql; + } else { + sql = virtualSql; + } } + return query('getTabCounters', sql, {}); } - return query('getTabCounters', sql, {}); -} export const getTabVirtualCounters = (virtualFilterIds: Array, startTime: number) => query( @@ -1352,7 +1351,8 @@ export const queryVirtualMemory = (): Promise> => export const queryVirtualMemoryData = (filterId: number): Promise> => query( 'queryVirtualMemoryData', - `select ts-${(window as any).recordStartNS + `select ts-${ + (window as any).recordStartNS } as startTime,value,filter_id as filterID from sys_mem_measure where filter_id=$filter_id`, { $filter_id: filterId } ); @@ -1428,35 +1428,6 @@ order by start_name;`, { $pid: pid } ); -export const queryProcessAllAppStartup = (pids: Array): Promise> => - query( - 'queryProcessStartup', - ` - select - P.pid, - A.tid, - A.call_id as itid, - (case when A.start_time < B.start_ts then 0 else (A.start_time - B.start_ts) end) as startTs, - (case - when A.start_time < B.start_ts then (A.end_time - B.start_ts) - when A.end_time = -1 then 0 - else (A.end_time - A.start_time) end) as dur, - A.start_name as startName -from app_startup A,trace_range B -left join process P on A.ipid = P.ipid -where P.pid in(${pids.join(',')}) -order by start_name;`, - { $pid: pids } - ); - -export const querySingleAppStartupsName = (pid: number): Promise> => - query( - 'queryAllAppStartupsName', - `select name from process - where pid=$pid`, - { $pid: pid } - ) - export const queryProcessSoMaxDepth = (): Promise> => query( 'queryProcessSoMaxDepth', @@ -3995,9 +3966,11 @@ export const queryEbpfSamplesCount = (startTime: number, endTime: number, ipids: select fsCount, vmCount from -(select count(1) as fsCount from file_system_sample s,trace_range t where s.end_ts between $startTime + t.start_ts and $endTime + t.start_ts ${ipids.length > 0 ? `and s.ipid in (${ipids.join(',')})` : '' +(select count(1) as fsCount from file_system_sample s,trace_range t where s.end_ts between $startTime + t.start_ts and $endTime + t.start_ts ${ + ipids.length > 0 ? `and s.ipid in (${ipids.join(',')})` : '' }) -,(select count(1) as vmCount from paged_memory_sample s,trace_range t where s.end_ts between $startTime + t.start_ts and $endTime + t.start_ts ${ipids.length > 0 ? `and s.ipid in (${ipids.join(',')})` : '' +,(select count(1) as vmCount from paged_memory_sample s,trace_range t where s.end_ts between $startTime + t.start_ts and $endTime + t.start_ts ${ + ipids.length > 0 ? `and s.ipid in (${ipids.join(',')})` : '' }); `, { $startTime: startTime, $endTime: endTime } @@ -5646,6 +5619,9 @@ export const queryTraceType = (): Promise< m.name = 'source_type';` ); +export const queryTransferList = (): Promise> => + query('queryTransferList', `select id, report_value as cmdStr from perf_report where report_type = 'config_name'`); + export const getTabRunningPercent = (tIds: Array, leftNS: number, rightNS: number): Promise> => query( 'getTabRunningPercent', @@ -5677,8 +5653,16 @@ export const querySearchFuncData = ( 'querySearchFuncData', ` select + c.cookie, + c.id, + c.name as funName, c.ts - r.start_ts as startTime, - c.dur + c.dur, + c.depth, + t.tid, + t.name as threadName, + p.pid, + 'func' as type from callstack c left join @@ -5697,7 +5681,8 @@ export const querySearchFuncData = ( t.tid = ${tIds} and not ((startTime < ${leftNS}) or (startTime > ${rightNS})); - ` + `, + { $search: funcName } ); export const queryCpuFreqUsageData = (Ids: Array): Promise> => @@ -5766,15 +5751,15 @@ export const queryHiSysEventData = (): Promise> => ORDER BY S.ts` ); -export const querySearchRowFuncData = ( - funcName: string, - tIds: number, - leftNS: number, - rightNS: number -): Promise> => - query( - 'querySearchRowFuncData', - ` + export const querySearchRowFuncData = ( + funcName: string, + tIds: number, + leftNS: number, + rightNS: number + ): Promise> => + query( + 'querySearchRowFuncData', + ` select c.name as funName, c.ts - r.start_ts as startTime, @@ -5800,366 +5785,5 @@ export const querySearchRowFuncData = ( and not ((startTime < ${leftNS}) or (startTime > ${rightNS})); `, - { $search: funcName } - ); - -export const queryTransferList = (): Promise> => - query( - 'queryTransferList', - `SELECT - id, - report_value as cmdStr - FROM - perf_report - WHERE - report_type = 'config_name'` - ); - -export const getTabBindersCount = (pIds: number[], tIds: number[], leftNS: number, rightNS: number): Promise> => - query( - 'getTabBindersCount', - ` - SELECT - c.name, - c.dur, - 1 AS count, - c.ts, - c.ts - r.start_ts AS startTime, - c.ts -r.start_ts + c.dur AS endTime, - t.tid, - p.pid, - ${leftNS} AS cycleStartTime, - (${rightNS} - ${leftNS}) AS cycleDur - FROM - callstack c, trace_range r - LEFT JOIN - thread t - ON - c.callid = t.id - LEFT JOIN - process p - ON - t.ipid = p.id - WHERE - c.name in ('binder transaction', 'binder async rcv', 'binder reply', 'binder transaction async') - AND - t.tid in (${tIds.join(',')}) - AND - p.pid in (${pIds.join(',')}) - AND NOT - ((startTime < ${leftNS}) - OR - (endTime > ${rightNS})); - `, - { - $leftNS: leftNS, - $rightNS: rightNS - } - ); - -export const queryBinderByThreadId = (pIds: number[], tIds: Array, leftNS: number, rightNS: number): Promise> => - query( - 'queryBinderByThreadId', - ` - SELECT - c.name, - c.ts - r.start_ts AS ts, - c.dur, - c.ts - r.start_ts AS startTime, - c.ts - r.start_ts + c.dur AS endTime, - t.tid, - p.pid - FROM - callstack c, trace_range r - LEFT JOIN - thread t - ON - c.callid = t.id - LEFT JOIN - process p - ON - t.ipid = p.id - WHERE - c.name in ('binder transaction', 'binder async rcv', 'binder reply', 'binder transaction async') - AND - t.tid in (${tIds.join(',')}) - AND - p.pid in (${pIds.join(',')}) - AND NOT - ((startTime < ${leftNS}) - OR - (endTime > ${rightNS})) - `, - { - $tIds: tIds, - $leftNS: leftNS, - $rightNS: rightNS - } - ); - - -export const querySingleFuncNameCycle = (funcName: string, tIds: string, leftNS: number, rightNS: number): Promise> => - query( - 'querySingleFuncNameCycle', - ` - SELECT - c.name AS funcName, - c.ts - r.start_ts AS cycleStartTime, - c.dur AS cycleDur, - c.id, - t.tid, - p.pid, - c.ts - r.start_ts + c.dur AS endTime - FROM - callstack c, trace_range r - LEFT JOIN - thread t - ON - c.callid = t.id - LEFT JOIN - process p - ON - t.ipid = p.id - WHERE - c.name = '${funcName}' - AND - t.tid = ${tIds} - AND NOT - ((cycleStartTime < ${leftNS}) - OR - (endTime > ${rightNS})) - `, - { - $funcName: funcName, - $tIds: tIds, - $leftNS: leftNS, - $rightNS: rightNS - } - ); - -export const queryLoopFuncNameCycle = (funcName: string, tIds: string, leftNS: number, rightNS: number): Promise> => - query( - 'queryLoopFuncNameCycle', - ` - SELECT - c.name AS funcName, - c.ts - r.start_ts AS cycleStartTime, - 0 AS cycleDur, - c.id, - t.tid, - p.pid - FROM - callstack c, trace_range r - LEFT JOIN - thread t - ON - c.callid = t.id - LEFT JOIN - process p - ON - t.ipid = p.id - WHERE - c.name = '${funcName}' - AND - t.tid = ${tIds} - AND NOT - ((cycleStartTime < ${leftNS}) - OR - (cycleStartTime > ${rightNS})) - `, - { - $funcName: funcName, - $tIds: tIds, - $leftNS: leftNS, - $rightNS: rightNS - } - ); - - - export const querySchedThreadStates = (tIds: Array, leftStartNs: number, rightEndNs: number): Promise> => - query( - 'getTabThreadStates', - ` - select - B.id, - B.pid, - B.tid, - B.state, - B.type, - B.dur, - B.ts, - B.dur + B.ts as endTs - from - thread_state AS B - where - B.tid in (${tIds.join(',')}) - and - not ((B.ts + ifnull(B.dur,0) < $leftStartNs) or (B.ts > $rightEndNs)) - order by - B.pid; - `, - { $leftStartNs: leftStartNs, $rightEndNs: rightEndNs } + { $search: funcName } ); - - export const querySingleCutData = (funcName: string, tIds: string, leftStartNs: number, rightEndNs: number): Promise> => - query( - 'querySingleCutData', - ` - select - c.id, - c.name, - c.ts as cycleStartTime, - c.ts + c.dur as cycleEndTime, - c.depth, - t.tid, - p.pid, - c.dur - from - callstack c - left join - thread t on c.callid = t.id - left join - process p on t.ipid = p.id - left join - trace_range r - where - c.name = '${funcName}' - and - t.tid = '${tIds}' - and - not ((c.ts < $leftStartNs) or (c.ts + ifnull(c.dur, 0) > $rightEndNs)) - `, - {$leftStartNs: leftStartNs, $rightEndNs: rightEndNs} - ) - - export const queryLoopCutData = ( funcName: string, tIds: string, leftStartNs: number, rightEndNs: number): Promise> => - query ( - 'queryLoopCutData', - ` - select - c.id, - c.name, - c.ts as cycleStartTime, - c.depth, - t.tid, - p.pid - from callstack c - left join - thread t on c.callid = t.id - left join - process p on t.ipid = p.id - where - c.name = '${funcName}' - and - t.tid = '${tIds}' - and - not ((c.ts < $leftStartNs) or (c.ts > $rightEndNs)) - order by - c.ts - `, - { $leftStartNs: leftStartNs, $rightEndNs: rightEndNs } - ) - export const getGpufreqData = (leftNS: number, rightNS: number, earliest: boolean): Promise> => { - let queryCondition = ''; - if (!earliest) { - queryCondition += ` where not ((s.ts - r.start_ts + ifnull(s.dur,0) < ${leftNS}) or (s.ts - r.start_ts > ${rightNS}))` - } - return query( - 'getGpufreqData', - ` - with state as - (select - name, - filter_id, - ts, - endts, - endts-ts as dur, - type, - value - from - (select - measure.filter_id, - clock_event_filter.name, - measure.ts, - lead(ts, 1, null) over( order by measure.ts) endts, - measure.type, - measure.value - from - clock_event_filter, - trace_range - left join - measure - where - clock_event_filter.name = 'gpufreq' - and - clock_event_filter.type = 'clock_set_rate' - and - clock_event_filter.id = measure.filter_id - order by measure.ts) - where endts is not null - ) - select - s.name as thread, - s.filter_id as filterId, - s.value/1000000 as freq, - s.value*s.dur as count, - s.value, - s.ts, - s.ts-r.start_ts as startNS, - s.dur, - s.endts- r.start_ts as endTime - from - state s, - trace_range r - ${queryCondition} - order by ts - `, - { $leftNS: leftNS, $rightNS: rightNS } - ); - } - - export const getGpufreqDataCut = (tIds: string, funcName: string, leftNS: number, rightNS: number, single: boolean, loop: boolean): Promise> => { - let queryCondition = ''; - if (single) { - queryCondition += `select s.funName,s.startTime,s.dur,s.startTime+s.dur as endTime,s.depth,s.tid,s.threadName,s.pid from state s - where endTime between ${leftNS} and ${rightNS}`; - } - if (loop) { - queryCondition += `select s.funName,s.startTime,s.loopEndTime-s.startTime as dur,s.loopEndTime as endTime,s.depth,s.tid,s.threadName,s.pid from state s - where endTime between ${leftNS} and ${rightNS} `; - } - return query( - 'getGpufreqDataCut', - ` - with state as - (select - * - from - (select - c.name as funName, - c.ts - r.start_ts as startTime, - c.dur, - lead(c.ts - r.start_ts, 1, null) over( order by c.ts - r.start_ts) loopEndTime, - c.depth, - t.tid, - t.name as threadName, - p.pid - from - callstack c - left join - thread t on c.callid = t.id - left join - process p on t.ipid = p.id - left join - trace_range r - where - c.name like '%${funcName}%' - and - tid = '${tIds}' - and - startTime between ${leftNS} and ${rightNS})) - ${queryCondition} - `, - { $search: funcName } - ); - } diff --git a/ide/src/trace/database/ui-worker/ProcedureWorker.ts b/ide/src/trace/database/ui-worker/ProcedureWorker.ts index 1a6bbab86..0fd1daf60 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorker.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorker.ts @@ -58,9 +58,6 @@ import { SnapshotRender } from './ProcedureWorkerSnapshot.js'; import { LogRender } from './ProcedureWorkerLog.js'; import { HiPerfCallChartRender } from './ProcedureWorkerHiPerfCallChart.js'; import { HiSysEventRender } from './ProcedureWorkerHiSysEvent.js'; -import { AllAppStartupRender } from './ProcedureWorkerAllAppStartup.js'; -import { FreqExtendRender } from './ProcedureWorkerFreqExtend.js'; -import { BinderRender } from './procedureWorkerBinder.js'; let dataList: any = {}; let dataList2: any = {}; @@ -80,7 +77,6 @@ export let renders: any = { 'file-system-cell': new FileSystemRender(), process: new ProcessRender(), 'app-start-up': new AppStartupRender(), - 'all-app-start-up': new AllAppStartupRender(), 'app-so-init': new SoRender(), heap: new HeapRender(), 'heap-timeline': new HeapTimelineRender(), @@ -117,8 +113,6 @@ export let renders: any = { snapshot: new SnapshotRender(), logs: new LogRender(), hiSysEvent: new HiSysEventRender(), - 'freq-extend': new FreqExtendRender(), - 'binder' : new BinderRender() }; function match(type: string, req: RequestMessage): void { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerAllAppStartup.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerAllAppStartup.ts deleted file mode 100644 index ede7a8369..000000000 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerAllAppStartup.ts +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { BaseStruct, dataFilterHandler, drawString } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { querySingleAppStartupsName } from '../SqlLite.js'; - -export class AllAppStartupRender { - renderMainThread( - req: { - appStartupContext: CanvasRenderingContext2D; - useCache: boolean; - type: string; - }, - appStartUpRow: TraceRow - ): void { - let list = appStartUpRow.dataList; - let filter = appStartUpRow.dataListCache; - dataFilterHandler(list, filter, { - startKey: 'startTs', - durKey: 'dur', - startNS: TraceRow.range?.startNS ?? 0, - endNS: TraceRow.range?.endNS ?? 0, - totalNS: TraceRow.range?.totalNS ?? 0, - frame: appStartUpRow.frame, - paddingTop: 5, - useCache: req.useCache || !(TraceRow.range?.refresh ?? false), - }); - req.appStartupContext.globalAlpha = 0.6; - let find = false; - let offset = 3; - for (let re of filter) { - AllAppStartupStruct.draw(req.appStartupContext, re); - if (appStartUpRow.isHover) { - if ( - re.frame && - appStartUpRow.hoverX >= re.frame.x - offset && - appStartUpRow.hoverX <= re.frame.x + re.frame.width + offset - ) { - AllAppStartupStruct.hoverStartupStruct = re; - find = true; - } - } - } - if (!find && appStartUpRow.isHover) { - AllAppStartupStruct.hoverStartupStruct = undefined; - } - } -} - -const padding = 3; - -export class AllAppStartupStruct extends BaseStruct { - static hoverStartupStruct: AllAppStartupStruct | undefined; - static selectStartupStruct: AllAppStartupStruct | undefined; - dur: number | undefined; - value: string | undefined; - startTs: number | undefined; - pid: number | undefined; - process: string | undefined; - itid: number | undefined; - endItid: number | undefined; - tid: number | undefined; - startName: number | undefined; - stepName: string | undefined; - - static draw(ctx: CanvasRenderingContext2D, data: AllAppStartupStruct): void { - if (data.frame) { - ctx.globalAlpha = 1.0; - ctx.fillStyle = ColorUtils.colorForTid(data.startName!); - ctx.fillRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height); - if (data.frame.width > 7) { - ctx.textBaseline = 'middle'; - ctx.lineWidth = 1; - let draAppName: string | undefined = ''; - if(data.stepName){ - draAppName = `${data.stepName} (${(data.dur! / 1000000).toFixed(2)}ms)`; - } - let textColor = - ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.stepName || '', 0, ColorUtils.FUNC_COLOR.length)]; - ctx.fillStyle = ColorUtils.funcTextColor(textColor); - drawString(ctx, draAppName, 2, data.frame, data); - } - if (data === AllAppStartupStruct.selectStartupStruct) { - ctx.strokeStyle = '#232c5d'; - ctx.lineWidth = 2; - ctx.strokeRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height); - } - } - } - - static async getStartupName(pid: number): Promise { - let singleAppName = await querySingleAppStartupsName(pid); - return singleAppName[0].name; - } -} diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts index a7d0e1ca1..c37ed2773 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts @@ -48,10 +48,10 @@ export class RequestMessage { totalNS: any; slicesTime: | { - startTime: number | null; - endTime: number | null; - color: string | null; - } + startTime: number | null; + endTime: number | null; + color: string | null; + } | undefined; range: any; scale: any; @@ -64,9 +64,9 @@ export class RequestMessage { id: any; postMessage: | { - (message: any, targetOrigin: string, transfer?: Transferable[]): void; - (message: any, options?: WindowPostMessageOptions): void; - } + (message: any, targetOrigin: string, transfer?: Transferable[]): void; + (message: any, options?: WindowPostMessageOptions): void; + } | undefined; } @@ -99,8 +99,8 @@ export function ns2Timestamp(ns: number): string { return `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}:${second .toString() .padStart(2, '0')}:${millisecond.toString().padStart(3, '0')}:${microsecond - .toString() - .padStart(3, '0')}:${nanosecond.toString().padStart(3, '0')}`; + .toString() + .padStart(3, '0')}:${nanosecond.toString().padStart(3, '0')}`; } const offsetX = 5; @@ -476,7 +476,6 @@ export class Point { export enum LineType { brokenLine, bezierCurve, - StraightLine } export class PairPoint { @@ -489,7 +488,6 @@ export class PairPoint { lineType?: LineType; business: string = ''; hidden?: boolean = false; - backrowEL?: TraceRow; constructor( rowEL: TraceRow, x: number, @@ -539,10 +537,10 @@ export function drawFlagLine( frame: any, slicesTime: | { - startTime: number | null | undefined; - endTime: number | null | undefined; - color: string | null | undefined; - } + startTime: number | null | undefined; + endTime: number | null | undefined; + color: string | null | undefined; + } | undefined ) { if (commonCtx) { @@ -745,97 +743,97 @@ export function drawSelectionRange(context: any, params: TraceRow) { context.globalAlpha = 1; } - // 绘制方法H:RSMainThread::DoComposition平均帧率的箭头指示线条 - if (params._docompositionList?.length) { - const rateList: Array = [...new Set(params.docompositionList)]; - if (rateList.length >= 2) { - // 计算平均帧率 - let cutres: number = (rateList[rateList.length - 1]! - rateList[0]!); - let avgFrameRate: string = ((rateList.length - 1) / cutres * 1000000000).toFixed(1) + 'fps'; - - let avgRateStartX = Math.floor( - ns2x( - rateList[0]!, - TraceRow.range?.startNS ?? 0, - TraceRow.range?.endNS ?? 0, - TraceRow.range?.totalNS ?? 0, - params.frame - ) - ); - let avgRateEndX = Math.floor( - ns2x( - rateList[rateList.length - 1]!, - TraceRow.range?.startNS ?? 0, - TraceRow.range?.endNS ?? 0, - TraceRow.range?.totalNS ?? 0, - params.frame - ) - ); - const textWidth = context.measureText(avgFrameRate).width; - const textHeight = 25; - const padding = 5; - let textX = Math.floor(ns2x( - (rateList[0]! + rateList[rateList.length - 1]!) / 2, + // 绘制方法H:RSMainThread::DoComposition平均帧率的箭头指示线条 + if (params._docompositionList?.length) { + const rateList: Array = [...new Set(params.docompositionList)]; + if (rateList.length >= 2) { + // 计算平均帧率 + let cutres: number = (rateList[rateList.length - 1]! - rateList[0]!); + let avgFrameRate: string = ((rateList.length - 1) / cutres * 1000000000).toFixed(1) + 'fps'; + + let avgRateStartX = Math.floor( + ns2x( + rateList[0]!, TraceRow.range?.startNS ?? 0, TraceRow.range?.endNS ?? 0, TraceRow.range?.totalNS ?? 0, params.frame - )) - textWidth / 2; - const textY = params.frame.y + 25; - - //左移到边界,不画线和文字 - if (avgRateStartX <= 0) { - avgRateStartX = -100; - } - if (avgRateEndX <= 0) { - avgRateEndX = -100; - } - if (textX <= 0) { - textX = -100; - } - //右移到边界,不画线和文字 - if (textX + textWidth / 2 >= params.frame.width) { - textX = params.frame.width + 100 - } - if (avgRateStartX >= params.frame.width) { - avgRateStartX = params.frame.width + 100; - } - if (avgRateEndX >= params.frame.width) { - avgRateEndX = params.frame.width + 100; - } - // 绘制文字背景矩形 - context.fillStyle = 'red'; - context.fillRect(textX - padding, textY - textHeight + padding, textWidth + padding * 2, textHeight - padding * 2); + ) + ); + let avgRateEndX = Math.floor( + ns2x( + rateList[rateList.length - 1]!, + TraceRow.range?.startNS ?? 0, + TraceRow.range?.endNS ?? 0, + TraceRow.range?.totalNS ?? 0, + params.frame + ) + ); + const textWidth = context.measureText(avgFrameRate).width; + const textHeight = 25; + const padding = 5; + let textX = Math.floor(ns2x( + (rateList[0]! + rateList[rateList.length - 1]!) / 2, + TraceRow.range?.startNS ?? 0, + TraceRow.range?.endNS ?? 0, + TraceRow.range?.totalNS ?? 0, + params.frame + )) - textWidth / 2; + const textY = params.frame.y + 25; - context.lineWidth = 2; - context.strokeStyle = 'yellow'; - context.beginPath(); - context.moveTo(avgRateStartX, textY); - context.lineTo(avgRateEndX, textY); - context.stroke(); - - const arrowSize = 5.5; - const arrowHead = (x: number, y: number, direction: 'left' | 'right') => { - context.beginPath(); - const headX = x + (direction === 'left' ? arrowSize : -arrowSize); - const headY = y - arrowSize / 2; - context.moveTo(x, y); - context.lineTo(headX, headY); - context.lineTo(headX, y + arrowSize); - context.closePath(); - - context.fillStyle = 'yellow'; - context.fill(); - }; - arrowHead(avgRateStartX, textY - 1, 'left'); - arrowHead(avgRateEndX, textY - 1, 'right'); - - context.fillStyle = 'white'; - context.fillText(avgFrameRate, textX, textY - 8); + //左移到边界,不画线和文字 + if (avgRateStartX <= 0) { + avgRateStartX = -100; + } + if (avgRateEndX <= 0) { + avgRateEndX = -100; + } + if (textX <= 0) { + textX = -100; } + //右移到边界,不画线和文字 + if (textX + textWidth / 2 >= params.frame.width) { + textX = params.frame.width + 100 + } + if (avgRateStartX >= params.frame.width) { + avgRateStartX = params.frame.width + 100; + } + if (avgRateEndX >= params.frame.width) { + avgRateEndX = params.frame.width + 100; + } + // 绘制文字背景矩形 + context.fillStyle = 'red'; + context.fillRect(textX - padding, textY - textHeight + padding, textWidth + padding * 2, textHeight - padding * 2); + + context.lineWidth = 2; + context.strokeStyle = 'yellow'; + context.beginPath(); + context.moveTo(avgRateStartX, textY); + context.lineTo(avgRateEndX, textY); + context.stroke(); + + const arrowSize = 5.5; + const arrowHead = (x: number, y: number, direction: 'left' | 'right') => { + context.beginPath(); + const headX = x + (direction === 'left' ? arrowSize : -arrowSize); + const headY = y - arrowSize / 2; + context.moveTo(x, y); + context.lineTo(headX, headY); + context.lineTo(headX, y + arrowSize); + context.closePath(); + + context.fillStyle = 'yellow'; + context.fill(); + }; + arrowHead(avgRateStartX, textY - 1, 'left'); + arrowHead(avgRateEndX, textY - 1, 'right'); + + context.fillStyle = 'white'; + context.fillText(avgFrameRate, textX, textY - 8); } } } +} export function drawWakeUp( wakeUpContext: CanvasRenderingContext2D | any, @@ -975,9 +973,6 @@ export function drawLinkLines( case LineType.bezierCurve: drawBezierCurve([newFirstNode, newSecondNode], maxWidth, context, percentage); break; - case LineType.StraightLine: - drawStraightLine([newFirstNode, newSecondNode], maxWidth, context); - break; default: drawBezierCurve([newFirstNode, newSecondNode], maxWidth, context, percentage); } @@ -1064,65 +1059,6 @@ function drawBezierCurve(it: PairPoint[], maxWidth: number, context: CanvasRende } } -function drawStraightLine(it: PairPoint[], maxWidth: number, context: CanvasRenderingContext2D) { - let startPoint = it[0].x > it[1].x ? it[1] : it[0]; - let endPoint = it[0].x > it[1].x ? it[0] : it[1]; - - let arrowSize = 8; - if (startPoint && endPoint) { - //左移到边界,不画线 - if (startPoint.x <= 0) { - startPoint.x = -100; - } - if (endPoint.x <= 0) { - endPoint.x = -100; - } - //右移到边界,不画线 - if (startPoint.x >= maxWidth) { - startPoint.x = maxWidth + 100; - } - if (endPoint.x >= maxWidth) { - endPoint.x = maxWidth + 100; - } - - context.beginPath(); - context.lineWidth = 2; - context.strokeStyle = '#0000FF'; - - context.moveTo(startPoint.x, startPoint.y); - context.lineTo(endPoint.x, endPoint.y); - - // 绘制箭头 - let arrow = Math.atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x); - context.moveTo(endPoint.x, endPoint.y); - context.lineTo( - endPoint.x - arrowSize * Math.cos(arrow - Math.PI / 6), - endPoint.y - arrowSize * Math.sin(arrow - Math.PI / 6) - ); - context.moveTo(endPoint.x, endPoint.y); - context.lineTo( - endPoint.x - arrowSize * Math.cos(arrow + Math.PI / 6), - endPoint.y - arrowSize * Math.sin(arrow + Math.PI / 6) - ); - - // 绘制另一端箭头 - arrow = Math.atan2(startPoint.y - endPoint.y, startPoint.x - endPoint.x); - context.moveTo(startPoint.x, startPoint.y); - context.lineTo( - startPoint.x - arrowSize * Math.cos(arrow - Math.PI / 6), - startPoint.y - arrowSize * Math.sin(arrow - Math.PI / 6) - ); - context.moveTo(startPoint.x, startPoint.y); - context.lineTo( - startPoint.x - arrowSize * Math.cos(arrow + Math.PI / 6), - startPoint.y - arrowSize * Math.sin(arrow + Math.PI / 6) - ); - - context.stroke(); - context.closePath(); - } -} - function drawBrokenLine(it: PairPoint[], maxWidth: number, context: CanvasRenderingContext2D): void { let brokenLineStart = it[0].x > it[1].x ? it[1] : it[0]; let brokenLineEnd = it[0].x > it[1].x ? it[0] : it[1]; @@ -1201,7 +1137,7 @@ export function drawLoading( frame: any, left: number, right: number -) { } +) {} export function drawString(ctx: CanvasRenderingContext2D, str: string, textPadding: number, frame: Rect, data: any) { if (data.textMetricsWidth === undefined) { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerFreqExtend.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerFreqExtend.ts deleted file mode 100644 index 3faaf8575..000000000 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerFreqExtend.ts +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { BaseStruct, dataFilterHandler, isFrameContainPoint, Render, RequestMessage } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; - -export class FreqExtendRender extends Render { - renderMainThread( - freqReq: { - context: CanvasRenderingContext2D; - useCache: boolean; - type: string; - }, - row: TraceRow - ) { - let freqList = row.dataList; - let freqFilter = row.dataListCache; - dataFilterHandler(freqList, freqFilter, { - startKey: 'startNS', - durKey: 'dur', - startNS: TraceRow.range?.startNS ?? 0, - endNS: TraceRow.range?.endNS ?? 0, - totalNS: TraceRow.range?.totalNS ?? 0, - frame: row.frame, - paddingTop: 5, - useCache: freqReq.useCache || !(TraceRow.range?.refresh ?? false), - }); - - if (row.isHover) { - CpuFreqExtendStruct.cycle = -1; - CpuFreqExtendStruct.isTabHover = false; - } - freqReq.context.beginPath(); - for (let re of freqFilter) { - if (row.isHover && re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) { - CpuFreqExtendStruct.hoverCpuFreqStruct = re; - } - if (!row.isHover && !CpuFreqExtendStruct.isTabHover) CpuFreqExtendStruct.hoverCpuFreqStruct = undefined; - CpuFreqExtendStruct.draw(freqReq.context, re); - } - freqReq.context.closePath(); - } -} - -export class CpuFreqExtendStruct extends BaseStruct { - static maxValue: number = 0; - static cycle: number = -1; - static isTabHover: boolean = false; - static hoverCpuFreqStruct: CpuFreqExtendStruct | undefined; - freq: number = 0; - static selectCpuFreqStruct: CpuFreqExtendStruct | undefined; - cpu: number | undefined; - value: number | undefined; - startNS: number | undefined; - dur: number | undefined; //自补充,数据库没有返回 - cycle: number | undefined; - - static draw(freqContext: CanvasRenderingContext2D, data: CpuFreqExtendStruct) { - if (data.frame) { - let width = data.frame.width || 0; - let index = data.cpu || 0; - index += 2; - freqContext.fillStyle = ColorUtils.colorForTid(index); - freqContext.strokeStyle = ColorUtils.colorForTid(index); - if (data === CpuFreqExtendStruct.hoverCpuFreqStruct - || data === CpuFreqExtendStruct.selectCpuFreqStruct - || data === CpuFreqExtendStruct.selectCpuFreqStruct - || (data.cycle === CpuFreqExtendStruct.cycle - && CpuFreqExtendStruct.cycle !== -1)) { - freqContext.fillStyle = '#ff0000'; - freqContext.strokeStyle = '#ff0000'; - freqContext.lineWidth = 3; - freqContext.globalAlpha = 0.6; - let drawHeight: number = Math.floor( - ((data.value || 0) * (data.frame.height || 0) * 1.0) / CpuFreqExtendStruct.maxValue - ); - if (drawHeight < 1) { - drawHeight = 1; - } - freqContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight, width, drawHeight); - freqContext.globalAlpha = 0.8; - freqContext.strokeRect(data.frame.x, data.frame.y + data.frame.height - drawHeight, width, drawHeight); - } else { - freqContext.globalAlpha = 0.6; - freqContext.lineWidth = 1; - let drawHeight: number = Math.floor(((data.value || 0) * (data.frame.height || 0)) / CpuFreqExtendStruct.maxValue); - if (drawHeight < 1) { - drawHeight = 1; - } - freqContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight, width, drawHeight); - } - } - freqContext.globalAlpha = 1.0; - freqContext.lineWidth = 1; - } -} diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts index 6a31c8939..b56d5dd76 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts @@ -58,7 +58,7 @@ export class ThreadRender extends Render { threadReq.context.closePath(); } - render(threadReq: RequestMessage, threadList: Array, threadFilter: Array) { } + render(threadReq: RequestMessage, threadList: Array, threadFilter: Array) {} } const padding = 3; @@ -71,7 +71,6 @@ export class ThreadStruct extends BaseThreadStruct { static sColor = '#FBFBFB'; static hoverThreadStruct: ThreadStruct | undefined; static selectThreadStruct: ThreadStruct | undefined; - static selectThreadStructList: Array = new Array(); argSetID: number | undefined; translateY: number | undefined; textMetricsWidth: number | undefined; diff --git a/ide/src/trace/database/ui-worker/procedureWorkerBinder.ts b/ide/src/trace/database/ui-worker/procedureWorkerBinder.ts deleted file mode 100644 index ee20c3fb6..000000000 --- a/ide/src/trace/database/ui-worker/procedureWorkerBinder.ts +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { BaseStruct, dataFilterHandler, isFrameContainPoint, Render, RequestMessage } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { drawString, Rect } from './ProcedureWorkerCommon.js'; - -export class BinderRender extends Render { - renderMainThread( - freqReq: { - context: CanvasRenderingContext2D; - useCache: boolean; - type: string; - }, - row: TraceRow - ) { - let freqList = row.dataList; - let freqFilter = row.dataListCache; - dataFilterHandler(freqList, freqFilter, { - startKey: 'startNS', - durKey: 'dur', - startNS: TraceRow.range?.startNS ?? 0, - endNS: TraceRow.range?.endNS ?? 0, - totalNS: TraceRow.range?.totalNS ?? 0, - frame: row.frame, - paddingTop: 5, - useCache: freqReq.useCache || !(TraceRow.range?.refresh ?? false), - }); - freqReq.context.beginPath(); - for (let re of freqFilter) { - if (row.isHover - && re.frame - && (re.frame.x < row.hoverX - && (binderStruct.maxHeight * 20 - re.depth * 20 + 20) < row.hoverY - && re.frame.x + re.frame.width > row.hoverX - && binderStruct.maxHeight * 20 - re.depth * 20 + re.value * 20 + 20 > row.hoverY)) { - binderStruct.hoverCpuFreqStruct = re; - } else { - binderStruct.hoverCpuFreqStruct = undefined; - } - binderStruct.draw(freqReq.context, re); - } - freqReq.context.closePath(); - } -} -export class binderStruct extends BaseStruct { - static hoverCpuFreqStruct: binderStruct | undefined; - static selectCpuFreqStruct: binderStruct | undefined; - static maxHeight: number = 0; - static hoverCycle: number = -1; - static isTableHover: boolean = false; - cpu: number | undefined; - value: number = 0; - cycle: number = -1; - startNS: number | undefined; - dur: number | undefined; //自补充,数据库没有返回 - name: string | undefined; - depth: number = 0; - static draw(freqContext: CanvasRenderingContext2D, data: binderStruct) { - if (data.frame) { - let index = data.cpu || 0; - let color = ''; - if (data.name === 'binder transaction') { - color = '#e86b6a'; - } - if (data.name === 'binder transaction async') { - color = '#7da6f4'; - } - if (data.name === 'binder reply') { - color = '#0cbdd4'; - } - if (data.name === 'binder async rcv') { - color = '#8770d3'; - } - freqContext.fillStyle = color - if (data === binderStruct.hoverCpuFreqStruct || data === binderStruct.selectCpuFreqStruct || (data.cycle === binderStruct.hoverCycle && binderStruct.isTableHover)) { - freqContext.globalAlpha = 1; - freqContext.lineWidth = 1; - freqContext.fillRect(data.frame.x, binderStruct.maxHeight * 20 - data.depth * 20 + 20, data.frame.width, data.value * 20); - } else { - freqContext.globalAlpha = 0.6; - freqContext.lineWidth = 1; - freqContext.fillRect(data.frame.x, binderStruct.maxHeight * 20 - data.depth * 20 + 20, data.frame.width, data.value * 20); - } - if (data.frame.width > 8) { - freqContext.lineWidth = 1; - freqContext.fillStyle = ColorUtils.funcTextColor( - ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.name || '', 0, ColorUtils.FUNC_COLOR.length)] - ); - freqContext.textBaseline = 'middle'; - drawString(freqContext, `${data.name || ''}`, 6, new Rect(data.frame.x, binderStruct.maxHeight * 20 - data.depth * 20 + 20, data.frame.width, data.value * 20), data); - } - freqContext.globalAlpha = 1.0; - freqContext.lineWidth = 1; - } - } -} \ No newline at end of file diff --git a/trace_streamer/prebuilts/patch_hiperf/hiviewdfx_BUILD.gn b/trace_streamer/prebuilts/patch_hiperf/hiviewdfx_BUILD.gn index 089dcf09e..a0afe8d68 100644 --- a/trace_streamer/prebuilts/patch_hiperf/hiviewdfx_BUILD.gn +++ b/trace_streamer/prebuilts/patch_hiperf/hiviewdfx_BUILD.gn @@ -61,7 +61,7 @@ ohos_source_set("hiviewdfx_source") { "${THIRD_PARTY}/perf_include/hiviewdfx/faultloggerd/interfaces/innerkits/unwinder/dfx_symbols.cpp", ] if (is_debug) { - sources += [ "${THIRD_PARTY}/perf_include/hiviewdfx/faultloggerd/interfaces/innerkits/unwinder/dfx_accessor.cpp" ] + sources += ["${THIRD_PARTY}/perf_include/hiviewdfx/faultloggerd/interfaces/innerkits/unwinder/dfx_accessor.cpp",] } } -- Gitee From ed728bfbf7c6ff375b6e45b82e6ee2668aa4bf0d Mon Sep 17 00:00:00 2001 From: zhangzepeng Date: Tue, 5 Dec 2023 17:42:15 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E2=80=98feat=E5=AD=90=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=92=8C=E9=83=A8=E4=BB=B6=E8=87=AA=E5=AE=9A=E4=B9=89=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E5=8A=9F=E8=83=BD=E6=8F=90=E4=BA=A4=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzepeng --- ide/src/base-ui/icon.svg | 66 ++ .../trace/component/trace/base/TraceRow.ts | 10 +- .../component/trace/base/TraceRowConfig.ts | 655 +++++++++++++++--- ide/src/trace/config/customTempConfig.json | 54 ++ 4 files changed, 699 insertions(+), 86 deletions(-) create mode 100644 ide/src/trace/config/customTempConfig.json diff --git a/ide/src/base-ui/icon.svg b/ide/src/base-ui/icon.svg index 3e4d09f3f..5524fca98 100644 --- a/ide/src/base-ui/icon.svg +++ b/ide/src/base-ui/icon.svg @@ -475,4 +475,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ide/src/trace/component/trace/base/TraceRow.ts b/ide/src/trace/component/trace/base/TraceRow.ts index df8041dc4..dbe9b0a30 100644 --- a/ide/src/trace/component/trace/base/TraceRow.ts +++ b/ide/src/trace/component/trace/base/TraceRow.ts @@ -155,7 +155,7 @@ export class TraceRow extends HTMLElement { public isLoading: boolean = false; public tampName: string = ''; public readonly args: any; - public templateType: Array = []; + public templateType: Set = new Set(); private rootEL: HTMLDivElement | null | undefined; private nameEL: HTMLLabelElement | null | undefined; private rowSettingTree: LitTree | null | undefined; @@ -462,7 +462,9 @@ export class TraceRow extends HTMLElement { } addTemplateTypes(...type: string[]): void { - this.templateType.push(...type); + type.forEach(item => { + this.templateType.add(item); + }) if (this.hasParentRowEl) { this.toParentAddTemplateType(this); } @@ -471,7 +473,9 @@ export class TraceRow extends HTMLElement { toParentAddTemplateType = (currentRowEl: TraceRow): void => { let parentRow = currentRowEl.parentRowEl; if (parentRow !== undefined) { - parentRow.templateType.push(...currentRowEl.templateType); + currentRowEl.templateType.forEach(item => { + parentRow!.templateType.add(item); + }); if (parentRow.parentRowEl !== undefined) { this.toParentAddTemplateType(parentRow); } diff --git a/ide/src/trace/component/trace/base/TraceRowConfig.ts b/ide/src/trace/component/trace/base/TraceRowConfig.ts index 60e6c73da..f41dd593f 100644 --- a/ide/src/trace/component/trace/base/TraceRowConfig.ts +++ b/ide/src/trace/component/trace/base/TraceRowConfig.ts @@ -22,70 +22,104 @@ import { LitSearch } from '../search/Search.js'; import { TraceSheet } from './TraceSheet.js'; import { CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU.js'; import { type BaseStruct } from '../../../bean/BaseStruct.js'; +import { LitIcon } from '../../../../base-ui/icon/LitIcon.js'; @element('trace-row-config') export class TraceRowConfig extends BaseElement { static allTraceRowList: Array> = []; - selectTypeList: Array | undefined = []; + private selectTypeList: Array | undefined = []; + private subsystemSelectList: Array | undefined = []; private spSystemTrace: SpSystemTrace | null | undefined; private sceneTable: HTMLDivElement | null | undefined; private chartTable: HTMLDivElement | null | undefined; private inputElement: HTMLInputElement | null | undefined; + private configTitle: HTMLDivElement | null | undefined; private traceRowList: NodeListOf> | undefined; - - get value(): string { - return this.getAttribute('value') || ''; - } - - set value(value: string) { - this.setAttribute('value', value); - } + private exportFileIcon: LitIcon | null | undefined; + private openTempFile: HTMLInputElement | null | undefined; + private treeNodes: SubsystemNode[] = []; + private expandedNodeList: Set = new Set(); + private tempString: string | null = null; + private subSystemSearch: string | undefined; + private backTemp: LitIcon | null | undefined; + private backTableHTML: string | undefined; + private otherRowNames: Array = []; + private sceneList = [ + 'FrameTimeline', + 'TaskPool', + 'AnimationEffect', + 'AppStartup', + 'HiSysEvent', + 'EnergyEvent', + 'Memory', + 'ProcessMemory', + 'ArkTs', + 'NativeMemory', + 'HiPerf', + 'HiEBpf', + ]; static get observedAttributes(): string[] { return ['mode']; } init(): void { - let sceneList = [ - 'FrameTimeline', - 'TaskPool', - 'AnimationEffect', - 'AppStartup', - 'HiSysEvent', - 'EnergyEvent', - 'Memory', - 'ProcessMemory', - 'ArkTs', - 'NativeMemory', - 'HiPerf', - 'HiEBpf', - ]; this.selectTypeList = []; - this.sceneTable!.innerHTML = ''; - this.chartTable!.innerHTML = ''; + this.subsystemSelectList = []; + this.otherRowNames = []; this.inputElement!.value = ''; this.spSystemTrace = this.parentElement!.querySelector('sp-system-trace'); this.traceRowList = this.spSystemTrace!.shadowRoot?.querySelector('div[class=rows-pane]')!.querySelectorAll>( "trace-row[row-parent-id='']" ); - let allowSceneList: Array = []; TraceRowConfig.allTraceRowList.push(...this.traceRowList!); + this.refreshAllConfig(true, true); + } + + private refreshAllConfig( + isRefreshTopTable: boolean = false, + isRefreshBottomTable: boolean = false, + isSubSysConfig: boolean = false + ): void{ + let allowSceneList: Array = []; + this.selectTypeList = []; + let topPanel = new DocumentFragment(); + let bottomPanel = new DocumentFragment(); this.traceRowList!.forEach((traceRow: TraceRow) => { traceRow.setAttribute('scene', ''); - if (traceRow.templateType.length > 0) { - traceRow.templateType.forEach((type) => { - if (sceneList.indexOf(type) >= 0 && allowSceneList.indexOf(type) < 0) { - allowSceneList.push(type); - this.initConfigSceneTable(type); - } - }); + this.otherRowNames.push({ + nodeName: traceRow.name, + scene: [...traceRow.templateType] + }); + if (isRefreshTopTable) { + this.sceneTable!.innerHTML = ''; + if (traceRow.templateType.size > 0) { + traceRow.templateType.forEach((type) => { + if (this.sceneList.indexOf(type) >= 0 && allowSceneList.indexOf(type) < 0) { + allowSceneList.push(type); + this.initConfigSceneTable(type, topPanel); + } + }); + } + } + if (isRefreshBottomTable) { + if (isSubSysConfig) { + this.backTableHTML = ''; + this.chartTable!.innerHTML = ''; + } else { + this.removeAttribute('temp_config'); + this.backTableHTML = this.chartTable!.innerHTML; + this.chartTable!.innerHTML = ''; + this.initConfigChartTable(traceRow, bottomPanel); + } } - this.initConfigChartTable(traceRow); }); + this.sceneTable?.appendChild(topPanel); + this.chartTable?.appendChild(bottomPanel); } - initConfigSceneTable(item: string): void { + initConfigSceneTable(item: string, topPanel: DocumentFragment): void { let spliceIndex = 1; let div = document.createElement('div'); div.className = 'scene-option-div'; @@ -113,10 +147,10 @@ export class TraceRowConfig extends BaseElement { htmlDivElement.style.gridTemplateColumns = '1fr 1fr'; htmlDivElement.appendChild(div); htmlDivElement.appendChild(optionCheckBox); - this.sceneTable?.appendChild(htmlDivElement); + topPanel.appendChild(htmlDivElement); } - clearLines(type: string) { + clearLines(type: string): void { if (type === 'FrameTimeline' || type === 'AppStartup') { this.spSystemTrace?.removeLinkLinesByBusinessType('janks'); } else if (type === 'Task Pool') { @@ -124,10 +158,10 @@ export class TraceRowConfig extends BaseElement { } } - initConfigChartTable(row: TraceRow): void { + initConfigChartTable(row: TraceRow, bottomPanel: DocumentFragment): void { let templateType = ''; - if (row.templateType.length > 0) { - templateType = row.templateType.reduce((pre, cur) => `${pre}:${cur}`); + if (row.templateType.size > 0) { + templateType = [...row.templateType].reduce((pre, cur) => `${pre}:${cur}`); } let div = document.createElement('div'); div.className = 'chart-option-div chart-item'; @@ -172,7 +206,7 @@ export class TraceRowConfig extends BaseElement { } this.refreshSystemPanel(); }); - this.chartTable!.append(...[div, optionCheckBox]); + bottomPanel.append(...[div, optionCheckBox]); } resetChartOption(): void { @@ -205,16 +239,11 @@ export class TraceRowConfig extends BaseElement { traceRow.setAttribute('scene', ''); this.refreshChildRow(traceRow.childrenList, true); } else { - for (let index = 0; index < traceRow.templateType!.length; index++) { - let type = traceRow.templateType![index]; - if (this.selectTypeList!.indexOf(type) >= 0) { - isShowRow = true; - break; - } - } + let templateTypeList = [...traceRow.templateType]; + isShowRow = templateTypeList.some(type => this.selectTypeList!.includes(type)); traceRow.expansion = false; if (isShowRow) { - if (traceRow.templateType.length > 0) { + if (traceRow.templateType.size > 0) { traceRow.rowHidden = false; traceRow.setAttribute('scene', ''); if (traceRow.childrenList && traceRow.childrenList.length > 0) { @@ -236,19 +265,11 @@ export class TraceRowConfig extends BaseElement { } else { if (favoriteRow.parentRowEl) { favoriteRow.parentRowEl.expansion = false; - for (let index = 0; index < favoriteRow.parentRowEl!.templateType!.length; index++) { - if (this.selectTypeList!.indexOf(favoriteRow.parentRowEl!.templateType![index]) >= 0) { - isShowRow = true; - break; - } - } + let favoriteList = [...favoriteRow.parentRowEl!.templateType]; + isShowRow = favoriteList.some(type => this.selectTypeList!.includes(type)); } else { - for (let index = 0; index < favoriteRow.templateType!.length; index++) { - if (this.selectTypeList!.indexOf(favoriteRow.templateType![index]) >= 0) { - isShowRow = true; - break; - } - } + let typeList = [...favoriteRow.templateType]; + isShowRow = typeList.some(type => this.selectTypeList!.includes(type)); } if (isShowRow) { favoriteRow.rowHidden = false; @@ -259,10 +280,43 @@ export class TraceRowConfig extends BaseElement { } } }); - this.refreshSystemPanel(); + if(this.hasAttribute('temp_config')) { + // 按照this.selectTypeList 更新treeNodes + this.refreshNodes(this.treeNodes); + this.refreshTable(); + } + } + this.refreshSystemPanel(); + } + + refreshNodes(nodes: SubsystemNode[]): void { + if(this.selectTypeList?.length !== 0) { + for (let index = 0; index < nodes.length; index++) { + let item = nodes[index]; + let exists = false; + item.scene?.forEach(sceneItem => { + if (this.selectTypeList!.some(elem => elem === sceneItem)) { + exists = true; + return; + } + }); + if(exists) { + item.isCheck = true; + } else { + item.isCheck = false; + } + this.refreshNodes(item.children); + } + } else { + for (let index = 0; index < nodes.length; index++) { + let item = nodes[index]; + item.isCheck = true; + this.refreshNodes(item.children); + } } } + refreshChildRow(childRows: Array>, isShowScene: boolean = false): void { childRows.forEach((row) => { if (isShowScene) { @@ -311,12 +365,48 @@ export class TraceRowConfig extends BaseElement { this.spSystemTrace!.selectFlag = undefined; } - initElements(): void { } - - connectedCallback(): void { + initElements(): void { this.sceneTable = this.shadowRoot!.querySelector('#scene-select'); this.chartTable = this.shadowRoot!.querySelector('#chart-select'); this.inputElement = this.shadowRoot!.querySelector('input'); + this.backTemp = this.shadowRoot?.querySelector('#back-temp'); + this.openTempFile = this.shadowRoot?.querySelector('#open-temp-file'); + this.exportFileIcon = this.shadowRoot?.querySelector('#export-file-icon'); + let loadTemp = this.shadowRoot?.querySelector('#custom-temp'); + let openFileIcon = this.shadowRoot?.querySelector('#open-file-icon'); + this.configTitle = this.shadowRoot?.querySelector('#config_title'); + let jsonUrl = `https://${window.location.host.split(':')[0]}:${window. + location.port}/application/trace/config/customTempConfig.json`; + loadTemp!.addEventListener('click', () => { + fetch(jsonUrl).then((res) => { + if (res.ok) { + res.text().then((text) => { + this.tempString = text; + this.loadTempConfig(); + }); + } + })['catch']((err) => { + console.log(err); + }); + }); + openFileIcon!.addEventListener('click', () => { + this.openTempFile!.value = ''; + this.openTempFile?.click(); + }); + } + + private filterFilterSearch(): void { + this.shadowRoot!.querySelectorAll('.temp-chart-item').forEach((subSystemOption: HTMLElement) => { + this.subSystemSearch = subSystemOption.getAttribute('search_text') || ''; + if (this.subSystemSearch!.indexOf(this.inputElement!.value) < 0) { + subSystemOption.style.display = 'none'; + } else { + subSystemOption.style.display = 'grid'; + } + }); + } + + connectedCallback(): void { this.inputElement?.addEventListener('keyup', () => { this.shadowRoot!.querySelectorAll('.chart-item').forEach((elementOption: HTMLElement) => { let searchText = elementOption.getAttribute('search_text') || ''; @@ -326,8 +416,342 @@ export class TraceRowConfig extends BaseElement { elementOption.style.display = 'block'; } }); - this.value = this.inputElement!.value; + this.filterFilterSearch(); + }); + this.backTemp!.addEventListener('click', () => { + this.init(); + this.resetChartTable(); + this.backTemp!.style.display = 'none'; + this.exportFileIcon!.style.display = 'none'; + this.configTitle!.innerHTML = 'Timeline Details'; + }); + this.openTempFile!.addEventListener('change', (event) => { + let that = this; + let fileList = (event.target as HTMLInputElement).files; + if (fileList && fileList.length > 0) { + let file = fileList[0]; + if (file) { + let reader = new FileReader(); + reader.onload = (): void => { + that.tempString = reader.result as string; + that.loadTempConfig(); + }; + reader.readAsText(file); + } + } + }); + this.exportFileIcon!.addEventListener('click', () => { + this.exportConfig(); + }); + } + + exportConfig(): void { + let a = document.createElement('a'); + let encoder = new TextEncoder(); + let tempBuffer = encoder.encode(this.tempString!); + a.href = URL.createObjectURL(new Blob([tempBuffer])); + a.download = 'customTempConfig'; + a.click(); + window.URL.revokeObjectURL(a.href); + } + + loadTempConfig(): void { + this.selectTypeList = []; + this.subsystemSelectList = []; + this.otherRowNames = []; + this.refreshAllConfig(true, true); + this.resetChartTable(); + this.inputElement!.value = ''; + this.backTableHTML = this.chartTable?.innerHTML; + let configJson; + try { + configJson = JSON.parse(this.tempString!); + this.configTitle!.innerHTML = 'SubSystem Template'; + let subsystemsKey: string = 'subsystems'; + if(!configJson[subsystemsKey]) { + this.exportFileIcon!.style.display = 'none'; + this.backTemp!.style.display = 'none'; + this.configTitle!.innerHTML = 'Timeline Details'; + return; + } + } catch (e) { + this.exportFileIcon!.style.display = 'none'; + this.backTemp!.style.display = 'none'; + this.configTitle!.innerHTML = 'Timeline Details'; + return; + } + this.exportFileIcon!.style.display = 'block'; + this.backTemp!.style.display = 'block'; + let id = 0; + this.treeNodes = this.buildSubSystemTreeData(id, configJson); + this.buildTempOtherList(id); + this.setAttribute('temp_config', ''); + this.subsystemSelectList = []; + this.expandedNodeList.clear(); + this.refreshTable(); + } + + private buildSubSystemTreeData(id: number, configJson: any): SubsystemNode[] { + let subsystemsKey: string = 'subsystems'; + let keys = Object.keys(configJson); + let subSystems: SubsystemNode[] = []; + if (keys.indexOf(subsystemsKey) >= 0) { + let subsystemsData = configJson[subsystemsKey]; + for (let subIndex = 0; subIndex < subsystemsData.length; subIndex++) { + let currentSystemData = subsystemsData[subIndex]; + let currentSubName = currentSystemData.subsystem; + id++; + let subsystemStruct: SubsystemNode = { + id: id, + nodeName: currentSubName, + children: [], + depth: 1, + isCheck: true + }; + if (subSystems.indexOf(subsystemStruct) < 0) { + let currentCompDates = currentSystemData.components; + for (let compIndex = 0; compIndex < currentCompDates.length; compIndex++) { + let currentCompDate = currentCompDates[compIndex]; + let currentCompName = currentCompDate.component; + let currentChartDates = currentCompDate.charts; + id++; + let componentStruct: SubsystemNode = { + id: id, + parent: subsystemStruct, + nodeName: currentCompName, + children: [], + depth: 2, + isCheck: true + }; + for (let chartIndex = 0; chartIndex < currentChartDates.length; chartIndex++) { + let currentChartDate = currentChartDates[chartIndex]; + let currentChartName = currentChartDate.chartName; + let currentChartId = currentChartDate.chartId; + let findChartNames: Array | undefined = []; + let scene: string[] = []; + if (this.traceRowList) { + for (let index = 0; index < this.traceRowList.length; index++) { + let item = this.traceRowList[index]; + let chartId = ''; + let name = item.name; + let pattern = / (\d+)$/; + let match = item.name.match(pattern); + if (match) { + chartId = match[0].trim(); + name = item.name.split(match[0])[0]; + if (name !== 'Cpu') { + if (name.toLowerCase().endsWith(currentChartName.toLowerCase()) || currentChartId === chartId) { + scene.push(...item.templateType); + findChartNames.push(item.name); + } + } else { + if (name.toLowerCase().endsWith(currentChartName.toLowerCase())) { + scene.push(...item.templateType); + findChartNames.push(item.name); + } + } + } else { + if (item.name.toLowerCase().endsWith(currentChartName.toLowerCase())) { + scene.push(...item.templateType); + findChartNames.push(item.name); + } + } + } + } + findChartNames.forEach(currentChartName => { + id++; + let chartStruct: SubsystemNode = { + id: id, + parent: componentStruct, + nodeName: currentChartName, + children: [], + depth: 3, + isCheck: true, + scene: scene + }; + if (componentStruct.children.indexOf(chartStruct) < 0) { + let rowNumber = this.otherRowNames.findIndex(row => row.nodeName === chartStruct.nodeName); + if (rowNumber >= 0) { + this.otherRowNames.splice(rowNumber, 1); + } + componentStruct.children.push(chartStruct); + } + }); + } + if (subsystemStruct.children.indexOf(componentStruct) < 0) { + subsystemStruct.children.push(componentStruct); + } + } + subSystems.push(subsystemStruct); + } + } + } + return subSystems; + } + + refreshTable(): void { + this.chartTable!.innerHTML = ''; + this.subsystemSelectList = []; + for (let index = 0; index < this.treeNodes.length; index++) { + this.buildSubsystem(this.treeNodes[index]); + } + this.filterFilterSearch(); + } + + buildSubsystem(subsystemNode: SubsystemNode): void { + let subsystemDiv = document.createElement('div'); + subsystemDiv.className = 'layout temp-chart-item'; + subsystemDiv.title = subsystemNode.nodeName!; + subsystemDiv.setAttribute('search_text', subsystemNode.nodeName!); + if (subsystemNode.scene) { + subsystemDiv.title = subsystemNode.scene.toString(); + } + if (subsystemNode.depth !== 3) { + let container = document.createElement('div'); + container.style.display = 'flex'; + container.style.marginLeft = `${subsystemNode.depth * 25}px`; + container.style.alignItems = 'center'; + let expandIcon = document.createElement('lit-icon') as LitIcon; + expandIcon.name = 'caret-down'; + expandIcon.className = 'expand-icon'; + if (this.expandedNodeList.has(subsystemNode.id)) { + expandIcon.setAttribute('expansion', ''); + } else { + expandIcon.removeAttribute('expansion'); + } + expandIcon.addEventListener('click', () => { + this.changeNode(subsystemNode.id); + this.refreshTable(); + }); + let componentDiv = document.createElement('div'); + componentDiv.className = 'subsystem-div'; + componentDiv.textContent = subsystemNode.nodeName!; + container.appendChild(expandIcon); + container.appendChild(componentDiv); + subsystemDiv.appendChild(container); + } else { + let chartDiv = document.createElement('div'); + chartDiv.className = 'chart-option'; + chartDiv.textContent = subsystemNode.nodeName!; + subsystemDiv.appendChild(chartDiv); + } + let configCheckBox: LitCheckBox = new LitCheckBox(); + configCheckBox.className = 'scene-check-box temp-chart-item'; + configCheckBox.setAttribute('search_text', subsystemNode.nodeName!); + if(subsystemNode.scene) { + configCheckBox.title = subsystemNode.scene.toString(); + } + configCheckBox.checked = subsystemNode.isCheck!; + configCheckBox.addEventListener('change', () => { + this.spSystemTrace?.removeLinkLinesByBusinessType('janks'); + this.spSystemTrace?.removeLinkLinesByBusinessType('task'); + this.setChildIsSelect(subsystemNode, configCheckBox); + this.setParentSelect(subsystemNode, configCheckBox.checked); + this.refreshTable(); + if (subsystemNode.depth === 3) { + this.traceRowList?.forEach((row) => { + if (row.name === subsystemNode.nodeName) { + if (configCheckBox.checked) { + row.setAttribute('scene', ''); + row.removeAttribute('row-hidden'); + } else { + row.expansion = false; + row.removeAttribute('scene'); + row.setAttribute('row-hidden', ''); + } + } + }); + if (configCheckBox.checked) { + this.subsystemSelectList?.push({ + nodeName: subsystemNode.nodeName!, + scene: Array(configCheckBox.title) + }); + } else { + let chartNumber = this.subsystemSelectList?.findIndex(row => row.nodeName === subsystemNode.nodeName!); + if (chartNumber !== undefined && chartNumber !== null) { + this.subsystemSelectList?.splice(chartNumber, 1); + } + } + } + this.refreshSystemPanel(); }); + subsystemDiv.appendChild(configCheckBox); + this.chartTable?.appendChild(subsystemDiv); + if (subsystemNode.children && this.expandedNodeList.has(subsystemNode.id)) { + subsystemNode.children.forEach(item => { + this.buildSubsystem(item); + }); + } + } + + private buildTempOtherList(id: number): void { + let otherRootNode: SubsystemNode = { + children: [], depth: 1, id: id, nodeName: 'other', isCheck: true + }; + for (let index = 0; index < this.otherRowNames!.length; index++) { + otherRootNode.children.push({ + children: [], + depth: 3, + id: id++, + nodeName: this.otherRowNames![index].nodeName, + isCheck: true, + parent: otherRootNode, + scene: this.otherRowNames![index].scene + }); + } + this.treeNodes.push(otherRootNode); + } + + private setChildIsSelect(node: SubsystemNode, configCheckBox: LitCheckBox): void { + node.isCheck = configCheckBox.checked; + if (node.children.length > 0) { + node.children.forEach(childItem => { + if (childItem.depth === 3) { + if (configCheckBox.checked) { + this.subsystemSelectList?.push({ + nodeName: childItem.nodeName!, + scene: Array(configCheckBox.title) + }); + } else { + let chartNumber = this.subsystemSelectList?.findIndex(row => row.nodeName === node.nodeName!); + if (chartNumber !== undefined && chartNumber !== null) { + this.subsystemSelectList?.splice(chartNumber, 1); + } + } + this.traceRowList?.forEach((item) => { + if (item.name === childItem.nodeName) { + if (configCheckBox.checked) { + item.setAttribute('scene', ''); + item.removeAttribute('row-hidden'); + } else { + item.expansion = false; + item.removeAttribute('scene'); + item.setAttribute('row-hidden', ''); + } + } + }); + } + this.setChildIsSelect(childItem, configCheckBox); + }); + } + } + + private setParentSelect(node: SubsystemNode, isSelect: boolean): void { + if (!isSelect && node.parent) { + node.parent.isCheck = isSelect; + if (node.parent.parent) { + node.parent.parent.isCheck = isSelect; + } + } + } + + private changeNode(currentNode: number): void { + if (this.expandedNodeList.has(currentNode)) { + this.expandedNodeList['delete'](currentNode); + } else { + this.expandedNodeList.add(currentNode); + } + this.refreshTable(); } initHtml(): string { @@ -339,6 +763,7 @@ export class TraceRowConfig extends BaseElement { :host{ visibility: visible; background-color: #F6F6F6; + cursor: auto; } .config-title { height: 100px; @@ -369,9 +794,10 @@ export class TraceRowConfig extends BaseElement { flex-direction: row; align-items: center; padding-left: 15px; - padding-right: 15px; + padding-right: 20px; background-color: #F6F6F6; - height: 3.2em; + height: 3.4em; + flex-wrap: wrap; } .config-scene-select { height: auto; @@ -382,6 +808,12 @@ export class TraceRowConfig extends BaseElement { border-radius: 5px; border: solid 1px #e0e0e0; } + :host([temp_config]) .config-chart-select { + height: auto; + overflow-y: auto; + display: block; + padding: 0px; + } .config-chart-select { display: grid; height: inherit; @@ -408,6 +840,19 @@ export class TraceRowConfig extends BaseElement { line-height: 35px; margin-left: 28px; } + .subsystem-div { + height: 35px; + line-height: 35px; + margin-left: 10px; + } + .chart-option { + height: 35px; + line-height: 35px; + margin-left: 75px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } input{ border: 0; outline: none; @@ -431,7 +876,7 @@ export class TraceRowConfig extends BaseElement { justify-content: space-between; transition: all 0.3s; user-select:none; - width: 250px; + width: max-content; color: #ffffff; cursor: pointer; line-height: 40px; @@ -439,30 +884,59 @@ export class TraceRowConfig extends BaseElement { border:1px solid #dcdcdc; border-radius:16px; background-color: #FFFFFF; - height: 70%; - margin: auto 4.2em auto auto; + height: 30px; + } + .expand-icon:not([expansion]) { + transform: rotateZ(-90deg); + } + .layout { + display: grid; + grid-template-columns: 1fr 1fr; + } + .scene-check-box { + justify-self: center; + height: 100%; + } + .temp-icon { + margin-left: 20px; + width: 20px; }
    Display Template - + +
    - -
    Template Select
    + +
    Template Select
    -
    - -
    Timeline Details
    -
    -
    - -
    - +
    +
    + +
    Timeline Details
    +
    +
    +
    +
    + +
    + +
    +
    + + + + + +
    @@ -475,5 +949,20 @@ export class TraceRowConfig extends BaseElement { if (name === 'mode' && newValue === '') { this.init(); } - } + }; +} + +export interface SubsystemNode { + id: number; + parent?: SubsystemNode; + nodeName: string | undefined | null; + children: SubsystemNode[]; + depth: number; + isCheck?: boolean; + scene?: string[]; +} + +export interface SceneNode { + nodeName: string | undefined | null; + scene?: string[]; } diff --git a/ide/src/trace/config/customTempConfig.json b/ide/src/trace/config/customTempConfig.json new file mode 100644 index 000000000..dc74211f6 --- /dev/null +++ b/ide/src/trace/config/customTempConfig.json @@ -0,0 +1,54 @@ +{ + "subsystems": [ + { + "subsystem": "Cpu", + "components": [ + { + "component": "Cpu", + "charts": [ + {"chartName": "Cpu", "chartId": ""} + ] + }, + { + "component": "Cpu Frequency", + "charts": [ + {"chartName": "Cpu Frequency", "chartId": ""} + ] + }, + { + "component": "Cpu State", + "charts": [ + {"chartName": "Cpu State", "chartId": ""} + ] + }, + { + "component": "Cpu Freq Limit", + "charts": [ + {"chartName": "Cpu Freq Limit", "chartId": ""} + ] + } + ] + }, + { + "subsystem": "Irqs", + "components": [ + { + "component": "Irqs", + "charts": [ + {"chartName": "Irqs", "chartId": ""} + ] + } + ] + }, + { + "subsystem": "FrameTimeline", + "components": [ + { + "component": "FrameTimeline", + "charts": [ + {"chartName": "FrameTimeline", "chartId": ""} + ] + } + ] + }] +} -- Gitee From 6cef75fdc78d4b15f68ce3da2647bdf1d923e3a5 Mon Sep 17 00:00:00 2001 From: zhangzepeng Date: Tue, 5 Dec 2023 19:12:00 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E2=80=98feat1.=E6=94=AF=E6=8C=81=E6=B3=B3?= =?UTF-8?q?=E9=81=93=E5=9B=BE=E5=B1=95=E5=BC=80=E5=90=8E=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E6=97=B6=E7=AC=AC=E4=B8=80=E8=A1=8C=E5=86=BB=E7=BB=93=E6=96=B9?= =?UTF-8?q?=E4=BE=BF=E6=9F=A5=E7=9C=8B=E7=BA=BF=E7=A8=8B=E6=89=80=E5=B1=9E?= =?UTF-8?q?=E8=BF=9B=E7=A8=8B=E5=90=8D=E5=92=8Cid2.=E6=94=AF=E6=8C=81webpa?= =?UTF-8?q?ck=E6=89=93=E5=8C=85=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzepeng --- ide/{src => }/index.html | 2 - ide/package.json | 43 +++- ide/src/base-ui/button/LitButton.ts | 2 +- .../base-ui/chart/column/LitChartColumn.ts | 8 +- .../base-ui/chart/pagenation/PaginationBox.ts | 2 +- ide/src/base-ui/chart/pie/LitChartPie.ts | 10 +- ide/src/base-ui/checkbox/LitCheckBox.ts | 2 +- .../base-ui/checkbox/LitCheckBoxWithText.ts | 4 +- ide/src/base-ui/checkbox/LitCheckGroup.ts | 4 +- ide/src/base-ui/drawer/LitDrawer.ts | 2 +- ide/src/base-ui/headline/lit-headline.ts | 2 +- ide/src/base-ui/icon.svg | 93 ++++---- ide/src/base-ui/icon/LitIcon.ts | 2 +- ide/src/base-ui/menu/LitMainMenu.ts | 10 +- ide/src/base-ui/menu/LitMainMenuGroup.ts | 2 +- ide/src/base-ui/menu/LitMainMenuItem.ts | 2 +- ide/src/base-ui/modal/LitModal.ts | 2 +- ide/src/base-ui/popover/LitPopContent.ts | 2 +- ide/src/base-ui/popover/LitPopover.ts | 16 +- ide/src/base-ui/popover/LitPopoverTitle.ts | 2 +- ide/src/base-ui/popover/LitPopoverV.ts | 2 +- .../base-ui/progress-bar/LitProgressBar.ts | 2 +- ide/src/base-ui/radiobox/LitRadioBox.ts | 4 +- ide/src/base-ui/radiobox/LitRadioGroup.ts | 4 +- ide/src/base-ui/select/LitAllocationSelect.ts | 2 +- ide/src/base-ui/select/LitSelect.ts | 4 +- ide/src/base-ui/select/LitSelectOption.ts | 4 +- ide/src/base-ui/select/LitSelectV.ts | 6 +- ide/src/base-ui/slider/LitSlider.ts | 2 +- ide/src/base-ui/switch/lit-switch.ts | 2 +- ide/src/base-ui/table/LitPageTable.ts | 12 +- ide/src/base-ui/table/lit-table-column.ts | 2 +- ide/src/base-ui/table/lit-table-group.ts | 2 +- ide/src/base-ui/table/lit-table.ts | 22 +- ide/src/base-ui/tabs/lit-tabpane.ts | 4 +- ide/src/base-ui/tabs/lit-tabs.ts | 6 +- ide/src/base-ui/tree/LitTree.ts | 6 +- ide/src/base-ui/tree/LitTreeNode.ts | 8 +- ide/src/command/Cmd.ts | 6 +- ide/src/hdc/HdcDeviceManager.ts | 18 +- ide/src/hdc/common/Serialize.ts | 12 +- ide/src/hdc/common/Utils.ts | 4 +- ide/src/hdc/hdcclient/AsyncQueue.ts | 2 +- ide/src/hdc/hdcclient/DataListener.ts | 2 +- ide/src/hdc/hdcclient/FormatCommand.ts | 6 +- ide/src/hdc/hdcclient/HdcClient.ts | 30 +-- ide/src/hdc/hdcclient/HdcStream.ts | 16 +- ide/src/hdc/message/DataMessage.ts | 12 +- ide/src/hdc/message/PayloadHead.ts | 2 +- ide/src/hdc/message/PayloadProtect.ts | 2 +- ide/src/hdc/message/SessionHandShake.ts | 6 +- ide/src/hdc/message/USBHead.ts | 2 +- ide/src/hdc/transmission/DataProcessing.ts | 22 +- .../transmission/UsbTransmissionChannel.ts | 6 +- ide/src/index.ts | 3 + ide/src/js-heap/HeapDataInterface.ts | 8 +- ide/src/js-heap/LoadDatabase.ts | 12 +- ide/src/js-heap/logic/Allocation.ts | 4 +- ide/src/js-heap/logic/HeapLoader.ts | 8 +- ide/src/js-heap/model/DatabaseStruct.ts | 4 +- ide/src/js-heap/model/UiStruct.ts | 4 +- ide/src/js-heap/utils/Utils.ts | 4 +- .../statistics/util/SpStatisticsHttpUtil.ts | 2 +- ide/src/trace/SpApplication.ts | 88 +++---- ide/src/trace/bean/AbilityMonitor.ts | 2 +- ide/src/trace/bean/BaseStruct.ts | 2 +- ide/src/trace/bean/BoxSelection.ts | 20 +- ide/src/trace/bean/CpuFreqStruct.ts | 4 +- ide/src/trace/bean/CpuStruct.ts | 6 +- ide/src/trace/bean/EbpfStruct.ts | 2 +- ide/src/trace/bean/FpsStruct.ts | 6 +- ide/src/trace/bean/FrameChartStruct.ts | 8 +- ide/src/trace/bean/FuncStruct.ts | 8 +- ide/src/trace/bean/HeapStruct.ts | 6 +- ide/src/trace/bean/JanksStruct.ts | 2 +- ide/src/trace/bean/JsStruct.ts | 2 +- ide/src/trace/bean/NativeHook.ts | 4 +- ide/src/trace/bean/PerfProfile.ts | 2 +- ide/src/trace/bean/ProcessMemStruct.ts | 4 +- ide/src/trace/bean/ProcessStruct.ts | 6 +- ide/src/trace/bean/ThreadStruct.ts | 6 +- ide/src/trace/component/SpFlags.ts | 2 +- ide/src/trace/component/SpHelp.ts | 8 +- ide/src/trace/component/SpInfoAndStas.ts | 12 +- ide/src/trace/component/SpKeyboard.ts | 2 +- ide/src/trace/component/SpMetrics.ts | 10 +- ide/src/trace/component/SpQuerySQL.ts | 24 +- ide/src/trace/component/SpRecordTrace.ts | 66 +++--- ide/src/trace/component/SpSystemTrace.ts | 177 +++++++------- ide/src/trace/component/SpWelcomePage.ts | 2 +- ide/src/trace/component/StackBar.ts | 6 +- ide/src/trace/component/Utils.ts | 6 +- ide/src/trace/component/chart/FrameChart.ts | 10 +- .../trace/component/chart/PerfDataQuery.ts | 10 +- .../component/chart/SpAbilityMonitorChart.ts | 26 +-- ide/src/trace/component/chart/SpArkTsChart.ts | 32 +-- .../trace/component/chart/SpChartManager.ts | 58 ++--- ide/src/trace/component/chart/SpClockChart.ts | 18 +- ide/src/trace/component/chart/SpCpuChart.ts | 16 +- .../component/chart/SpFileSystemChart.ts | 18 +- ide/src/trace/component/chart/SpFpsChart.ts | 12 +- .../trace/component/chart/SpFrameTimeChart.ts | 30 +-- ide/src/trace/component/chart/SpFreqChart.ts | 22 +- ide/src/trace/component/chart/SpHiPerf.ts | 36 +-- .../component/chart/SpHiSysEnergyChart.ts | 24 +- .../component/chart/SpHiSysEventChart.ts | 10 +- ide/src/trace/component/chart/SpIrqChart.ts | 14 +- ide/src/trace/component/chart/SpLogChart.ts | 10 +- .../component/chart/SpNativeMemoryChart.ts | 22 +- .../trace/component/chart/SpProcessChart.ts | 34 +-- ide/src/trace/component/chart/SpSdkChart.ts | 18 +- .../component/chart/SpVirtualMemChart.ts | 12 +- .../trace/component/chart/SpVmTrackerChart.ts | 24 +- ide/src/trace/component/chart/VSync.ts | 4 +- .../schedulingAnalysis/CheckCpuSetting.ts | 10 +- .../schedulingAnalysis/DrawerCpuTabs.ts | 16 +- .../SpSchedulingAnalysis.ts | 18 +- .../schedulingAnalysis/TabCpuAnalysis.ts | 26 +-- .../TabCpuDetailsFrequency.ts | 26 +-- .../schedulingAnalysis/TabCpuDetailsIdle.ts | 24 +- .../schedulingAnalysis/TabCpuDetailsIrq.ts | 22 +- .../TabCpuDetailsThreads.ts | 18 +- .../schedulingAnalysis/TabThreadAnalysis.ts | 24 +- .../schedulingAnalysis/TableNoData.ts | 2 +- .../Top20FrequencyThread.ts | 28 +-- .../Top20ProcessSwitchCount.ts | 18 +- .../Top20ProcessThreadCount.ts | 20 +- .../schedulingAnalysis/Top20ThreadCpuUsage.ts | 30 +-- .../schedulingAnalysis/Top20ThreadRunTime.ts | 18 +- .../schedulingAnalysis/utils/Utils.ts | 2 +- .../trace/component/setting/SpAllocations.ts | 18 +- ide/src/trace/component/setting/SpArkTs.ts | 20 +- .../trace/component/setting/SpCheckDesBox.ts | 4 +- .../trace/component/setting/SpFileSystem.ts | 24 +- .../trace/component/setting/SpHilogRecord.ts | 16 +- .../trace/component/setting/SpHisysEvent.ts | 14 +- .../trace/component/setting/SpProbesConfig.ts | 12 +- .../trace/component/setting/SpRecordPerf.ts | 32 +-- .../component/setting/SpRecordSetting.ts | 16 +- .../component/setting/SpRecordTemplate.ts | 8 +- .../trace/component/setting/SpSdkConfig.ts | 18 +- .../trace/component/setting/SpTraceCommand.ts | 8 +- .../trace/component/setting/SpVmTracker.ts | 16 +- .../trace/component/setting/SpWebHdcShell.ts | 8 +- ide/src/trace/component/trace/SpChartList.ts | 20 +- .../component/trace/TimerShaftElement.ts | 24 +- .../trace/component/trace/base/ColorUtils.ts | 2 +- .../component/trace/base/CustomThemeColor.ts | 10 +- .../trace/component/trace/base/Extension.ts | 2 +- .../trace/component/trace/base/RangeSelect.ts | 14 +- .../trace/component/trace/base/TraceRow.ts | 50 ++-- .../component/trace/base/TraceRowConfig.ts | 20 +- .../component/trace/base/TraceRowObject.ts | 6 +- .../trace/base/TraceRowRecyclerView.ts | 8 +- .../trace/component/trace/base/TraceSheet.ts | 136 +++++------ .../component/trace/base/TraceSheetConfig.ts | 218 +++++++++--------- ide/src/trace/component/trace/base/Utils.ts | 6 +- .../trace/component/trace/search/Search.ts | 6 +- .../trace/component/trace/sheet/SheetUtils.ts | 4 +- .../component/trace/sheet/TabPaneCurrent.ts | 14 +- .../trace/sheet/TabPaneCurrentSelection.ts | 44 ++-- .../component/trace/sheet/TabPaneFilter.ts | 16 +- .../trace/sheet/TabPaneJsMemoryFilter.ts | 16 +- .../component/trace/sheet/TabProgressBar.ts | 2 +- .../trace/sheet/ability/TabPaneCpuAbility.ts | 18 +- .../trace/sheet/ability/TabPaneDiskAbility.ts | 18 +- .../trace/sheet/ability/TabPaneDmaAbility.ts | 16 +- .../ability/TabPaneDmaAbilityComparison.ts | 22 +- .../sheet/ability/TabPaneDmaSelectAbility.ts | 14 +- .../sheet/ability/TabPaneGpuMemoryAbility.ts | 20 +- .../ability/TabPaneGpuMemoryComparison.ts | 24 +- .../ability/TabPaneGpuMemorySelectAbility.ts | 12 +- .../sheet/ability/TabPaneHistoryProcesses.ts | 16 +- .../sheet/ability/TabPaneLiveProcesses.ts | 16 +- .../sheet/ability/TabPaneMemoryAbility.ts | 16 +- .../sheet/ability/TabPaneNetworkAbility.ts | 18 +- .../trace/sheet/ability/TabPanePurgPin.ts | 16 +- .../TabPanePurgPinComparisonAbility.ts | 18 +- .../sheet/ability/TabPanePurgPinSelection.ts | 16 +- .../trace/sheet/ability/TabPanePurgTotal.ts | 14 +- .../TabPanePurgTotalComparisonAbility.ts | 18 +- .../ability/TabPanePurgTotalSelection.ts | 16 +- .../trace/sheet/ark-ts/TabPaneComparison.ts | 22 +- .../trace/sheet/ark-ts/TabPaneJsCpu.ts | 16 +- .../sheet/ark-ts/TabPaneJsCpuBottomUp.ts | 8 +- .../sheet/ark-ts/TabPaneJsCpuCallTree.ts | 8 +- .../sheet/ark-ts/TabPaneJsCpuStatistics.ts | 20 +- .../trace/sheet/ark-ts/TabPaneSummary.ts | 26 +-- .../trace/sheet/clock/TabPaneClockCounter.ts | 8 +- .../trace/sheet/cpu/TabPaneBoxChild.ts | 14 +- .../trace/sheet/cpu/TabPaneCounterSample.ts | 26 +-- .../trace/sheet/cpu/TabPaneCpuByProcess.ts | 14 +- .../trace/sheet/cpu/TabPaneCpuByThread.ts | 16 +- .../trace/sheet/cpu/TabPaneCpuStateClick.ts | 8 +- .../trace/sheet/cpu/TabPaneCpuUsage.ts | 12 +- .../trace/sheet/cpu/TabPaneFrequencySample.ts | 23 +- .../component/trace/sheet/cpu/TabPanePTS.ts | 14 +- .../component/trace/sheet/cpu/TabPaneSPT.ts | 14 +- .../trace/sheet/cpu/TabPaneSchedPriority.ts | 16 +- .../sheet/energy/TabPaneEnergyAnomaly.ts | 14 +- .../trace/sheet/energy/TabPanePowerBattery.ts | 14 +- .../trace/sheet/energy/TabPanePowerDetails.ts | 16 +- .../sheet/energy/TabPaneSystemDetails.ts | 16 +- .../sheet/file-system/TabPaneCallTree.ts | 26 +-- .../file-system/TabPaneFileSystemCalltree.ts | 30 +-- .../TabPaneFileSystemDescHistory.ts | 16 +- .../TabPaneFileSystemDescTimeSlice.ts | 14 +- .../file-system/TabPaneFileSystemEvents.ts | 18 +- .../TabPaneFilesystemStatistics.ts | 12 +- .../TabPaneFilesystemStatisticsAnalysis.ts | 22 +- .../sheet/file-system/TabPaneIOCallTree.ts | 6 +- .../file-system/TabPaneIOTierStatistics.ts | 16 +- .../TabPaneIOTierStatisticsAnalysis.ts | 22 +- .../file-system/TabPaneIoCompletionTimes.ts | 18 +- .../sheet/file-system/TabPaneVMEvents.ts | 18 +- .../TabPaneVirtualMemoryStatistics.ts | 18 +- .../TabPaneVirtualMemoryStatisticsAnalysis.ts | 22 +- .../component/trace/sheet/fps/TabPaneFps.ts | 14 +- .../trace/sheet/frame/TabFrameSpacing.ts | 12 +- .../trace/sheet/frame/TabPaneFrameDynamic.ts | 14 +- .../trace/sheet/freq/TabPaneCpuFreqLimits.ts | 14 +- .../component/trace/sheet/freq/TabPaneFreq.ts | 10 +- .../trace/sheet/freq/TabPaneFreqLimit.ts | 10 +- .../sheet/frequsage/TabPaneFreqDataCut.ts | 14 +- .../trace/sheet/frequsage/TabPaneFreqUsage.ts | 16 +- .../trace/sheet/gpu/TabPaneGpuClickSelect.ts | 16 +- .../gpu/TabPaneGpuClickSelectComparison.ts | 26 +-- .../component/trace/sheet/gpu/TabPaneGpuGL.ts | 18 +- .../sheet/gpu/TabPaneGpuTotalBoxSelect.ts | 20 +- .../sheet/gpu/TabPaneGpuWindowBoxSelect.ts | 20 +- .../component/trace/sheet/gpu/TabPaneGraph.ts | 18 +- .../trace/sheet/hilog/TabPaneHiLogSummary.ts | 12 +- .../trace/sheet/hilog/TabPaneHiLogs.ts | 20 +- .../trace/sheet/hiperf/TabPanePerfAnalysis.ts | 22 +- .../trace/sheet/hiperf/TabPerfBottomUp.ts | 24 +- .../trace/sheet/hiperf/TabPerfProfile.ts | 32 +-- .../trace/sheet/hiperf/TabPerfSampleList.ts | 22 +- .../hisysevent/TabPaneHiSysEventSummary.ts | 12 +- .../sheet/hisysevent/TabPaneHisysEvents.ts | 26 +-- .../trace/sheet/irq/TabPaneIrqCounter.ts | 8 +- .../trace/sheet/jank/TabPaneFrames.ts | 8 +- .../sheet/native-memory/TabPaneNMCallTree.ts | 30 +-- .../native-memory/TabPaneNMSampleList.ts | 26 +-- .../TabPaneNMStatisticAnalysis.ts | 30 +-- .../sheet/native-memory/TabPaneNMStatstics.ts | 22 +- .../sheet/native-memory/TabPaneNMemory.ts | 30 +-- .../trace/sheet/process/TabPaneCounter.ts | 10 +- .../trace/sheet/process/TabPaneSlices.ts | 18 +- .../trace/sheet/process/TabPaneStartup.ts | 16 +- .../trace/sheet/process/TabPaneStaticInit.ts | 16 +- .../sheet/process/TabPaneThreadStates.ts | 18 +- .../trace/sheet/process/TabPaneThreadUsage.ts | 20 +- .../trace/sheet/sdk/TabPaneSdkCounter.ts | 16 +- .../trace/sheet/sdk/TabPaneSdkSlice.ts | 18 +- .../sheet/smaps/TabPaneSmapsComparison.ts | 20 +- .../trace/sheet/smaps/TabPaneSmapsRecord.ts | 22 +- .../trace/sheet/smaps/TabPaneSmapsSample.ts | 18 +- .../sheet/smaps/TabPaneSmapsStatistics.ts | 16 +- .../trace/sheet/task/TabPaneTaskFrames.ts | 14 +- .../vmtracker/TabPaneDmaSelectVmTracker.ts | 16 +- .../sheet/vmtracker/TabPaneDmaVmTracker.ts | 16 +- .../TabPaneDmaVmTrackerComparison.ts | 24 +- .../TabPaneGpuMemorySelectVmTracker.ts | 14 +- .../vmtracker/TabPaneGpuMemoryVmTracker.ts | 18 +- .../TabPaneGpuMemoryVmTrackerComparison.ts | 26 +-- .../vmtracker/TabPaneGpuResourceVmTracker.ts | 14 +- .../vmtracker/TabPanePurgPinComparisonVM.ts | 20 +- .../vmtracker/TabPanePurgTotalComparisonVM.ts | 20 +- .../sheet/vmtracker/TabPaneVmTrackerShm.ts | 12 +- .../TabPaneVmTrackerShmComparison.ts | 22 +- .../vmtracker/TabPaneVmTrackerShmSelection.ts | 14 +- .../trace/timer-shaft/CollapseButton.ts | 6 +- .../component/trace/timer-shaft/Graph.ts | 2 +- .../component/trace/timer-shaft/RangeRuler.ts | 180 +++++++-------- .../component/trace/timer-shaft/SportRuler.ts | 16 +- .../trace/timer-shaft/TabPaneFlag.ts | 14 +- .../component/trace/timer-shaft/TimeRuler.ts | 6 +- ide/src/trace/config/customTempConfig.json | 1 + ide/src/trace/database/Convert.ts | 22 +- ide/src/trace/database/DBUtils.ts | 2 +- ide/src/trace/database/LongTraceDBUtils.ts | 2 +- ide/src/trace/database/Procedure.ts | 43 ++-- ide/src/trace/database/SqlLite.ts | 130 ++++++----- ide/src/trace/database/SqlLiteWorker.ts | 3 +- ide/src/trace/database/TempSql.ts | 1 + ide/src/trace/database/TraceWorker.ts | 4 +- ide/src/trace/database/TraceWorkerRoot.ts | 36 --- .../logic-worker/ProcedureLogicWorker.ts | 16 +- .../ProcedureLogicWorkerCpuState.ts | 2 +- .../ProcedureLogicWorkerFileSystem.ts | 2 +- .../ProcedureLogicWorkerJsCpuProfiler.ts | 4 +- .../ProcedureLogicWorkerNativeNemory.ts | 4 +- .../logic-worker/ProcedureLogicWorkerPerf.ts | 6 +- .../logic-worker/ProcedureLogicWorkerSPT.ts | 4 +- .../ProcedureLogicWorkerSchedulingAnalysis.ts | 2 +- .../database/ui-worker/ProcedureWorker.ts | 90 ++++---- .../ui-worker/ProcedureWorkerAppStartup.ts | 6 +- .../database/ui-worker/ProcedureWorkerCPU.ts | 8 +- .../ui-worker/ProcedureWorkerClock.ts | 6 +- .../ui-worker/ProcedureWorkerCommon.ts | 6 +- .../ui-worker/ProcedureWorkerCpuAbility.ts | 8 +- .../ui-worker/ProcedureWorkerCpuFreqLimits.ts | 8 +- .../ui-worker/ProcedureWorkerCpuProfiler.ts | 8 +- .../ui-worker/ProcedureWorkerCpuState.ts | 8 +- .../ui-worker/ProcedureWorkerDiskIoAbility.ts | 6 +- .../ui-worker/ProcedureWorkerEnergyAnomaly.ts | 6 +- .../ui-worker/ProcedureWorkerEnergyPower.ts | 4 +- .../ui-worker/ProcedureWorkerEnergyState.ts | 4 +- .../ui-worker/ProcedureWorkerEnergySystem.ts | 4 +- .../database/ui-worker/ProcedureWorkerFPS.ts | 4 +- .../ui-worker/ProcedureWorkerFileSystem.ts | 4 +- .../ProcedureWorkerFrameAnimation.ts | 6 +- .../ui-worker/ProcedureWorkerFrameDynamic.ts | 8 +- .../ui-worker/ProcedureWorkerFrameSpacing.ts | 8 +- .../database/ui-worker/ProcedureWorkerFreq.ts | 6 +- .../database/ui-worker/ProcedureWorkerFunc.ts | 10 +- .../database/ui-worker/ProcedureWorkerHeap.ts | 6 +- .../ui-worker/ProcedureWorkerHeapSnapshot.ts | 6 +- .../ui-worker/ProcedureWorkerHeapTimeline.ts | 6 +- .../ui-worker/ProcedureWorkerHiPerfCPU.ts | 6 +- .../ProcedureWorkerHiPerfCallChart.ts | 8 +- .../ui-worker/ProcedureWorkerHiPerfEvent.ts | 6 +- .../ui-worker/ProcedureWorkerHiPerfProcess.ts | 6 +- .../ui-worker/ProcedureWorkerHiPerfReport.ts | 6 +- .../ui-worker/ProcedureWorkerHiPerfThread.ts | 6 +- .../ui-worker/ProcedureWorkerHiSysEvent.ts | 6 +- .../database/ui-worker/ProcedureWorkerIrq.ts | 6 +- .../database/ui-worker/ProcedureWorkerJank.ts | 8 +- .../database/ui-worker/ProcedureWorkerLog.ts | 8 +- .../database/ui-worker/ProcedureWorkerMem.ts | 10 +- .../ui-worker/ProcedureWorkerMemoryAbility.ts | 6 +- .../ProcedureWorkerNetworkAbility.ts | 6 +- .../ProcedureWorkerPerfCallchains.ts | 21 +- .../ui-worker/ProcedureWorkerProcess.ts | 8 +- .../ui-worker/ProcedureWorkerSnapshot.ts | 8 +- .../ui-worker/ProcedureWorkerSoInit.ts | 6 +- .../ui-worker/ProcedureWorkerThread.ts | 8 +- .../ui-worker/ProcedureWorkerTimeline.ts | 8 +- .../ui-worker/ProcedureWorkerVirtualMemory.ts | 6 +- .../ui-worker/ProduceWorkerSdkCounter.ts | 4 +- .../ui-worker/ProduceWorkerSdkSlice.ts | 6 +- ide/src/trace/grpc/HiProfilerClient.ts | 2 +- ide/tsconfig.json | 20 +- ide/webpack.config.js | 204 ++++++++++++++++ 344 files changed, 2919 insertions(+), 2679 deletions(-) rename ide/{src => }/index.html (84%) create mode 100644 ide/src/index.ts delete mode 100644 ide/src/trace/database/TraceWorkerRoot.ts create mode 100644 ide/webpack.config.js diff --git a/ide/src/index.html b/ide/index.html similarity index 84% rename from ide/src/index.html rename to ide/index.html index 370f725d0..e18941ebd 100644 --- a/ide/src/index.html +++ b/ide/index.html @@ -25,7 +25,5 @@ req.send(null); window.version = req.getResponseHeader('data-version') || ''; - - diff --git a/ide/package.json b/ide/package.json index adc2039b7..0f4542b70 100644 --- a/ide/package.json +++ b/ide/package.json @@ -4,9 +4,16 @@ "description": "Smart Perf", "main": "index.js", "scripts": { + "build": "webpack --mode=production --node-env=production", + "build:dev": "webpack --mode=development", + "build:prod": "webpack --mode=production --node-env=production", + "watch": "webpack --watch", + "serve": "webpack serve", "compile": "node ./build.js", + "statics": "node ./statisticsCheck.js", "test": "jest -u", - "test-c": "jest --coverage -u" + "test-c": "jest --coverage -u", + "lint": "npx eslint --ext .ts ./src/**" }, "jest": { "testEnvironment": "jsdom", @@ -41,20 +48,42 @@ "author": "", "license": "Apache License", "devDependencies": { + "@babel/core": "^7.23.2", "@babel/plugin-proposal-class-properties": "^7.16.7", "@babel/plugin-proposal-decorators": "^7.17.2", - "@babel/preset-env": "*", + "@babel/preset-env": "^7.23.2", "@babel/preset-typescript": "*", "@types/jest": "*", "@types/node": "^17.0.10", + "@typescript-eslint/eslint-plugin": "^5.59.9", + "@typescript-eslint/parser": "^5.59.11", + "@webpack-cli/generators": "^3.0.7", + "autoprefixer": "^10.4.14", + "babel-loader": "^9.1.3", + "clean-webpack-plugin": "^4.0.0", + "copy-webpack-plugin": "^11.0.0", + "css-loader": "^6.8.1", + "eslint": "^8.43.0", + "html-webpack-plugin": "^5.5.3", + "javascript-obfuscator": "^4.1.0", "jest": "*", "jest-canvas-mock": "^2.3.1", - "typescript": "^4.2.3", - "jsdom-worker": "^0.2.1", "jest-environment-jsdom": "^28.1.0", - "node-fetch": "^2.6.7", + "jsdom-worker": "^0.2.1", "log4js": "^6.4.4", - "usb": "^2.4.2" + "mini-css-extract-plugin": "^2.7.6", + "node-fetch": "^2.6.7", + "prettier": "^3.0.0", + "style-loader": "^3.3.3", + "ts-loader": "^9.4.4", + "typescript": "^5.2.2", + "usb": "^2.4.2", + "wasm-loader": "^1.3.0", + "webpack": "^5.89.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^4.15.1" }, - "dependencies": {} + "dependencies": { + "@webcomponents/custom-elements": "^1.6.0" + } } diff --git a/ide/src/base-ui/button/LitButton.ts b/ide/src/base-ui/button/LitButton.ts index c3604bf9b..9c2c9b12d 100644 --- a/ide/src/base-ui/button/LitButton.ts +++ b/ide/src/base-ui/button/LitButton.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-button') export class LitButton extends BaseElement { diff --git a/ide/src/base-ui/chart/column/LitChartColumn.ts b/ide/src/base-ui/chart/column/LitChartColumn.ts index 818412eba..acf163198 100644 --- a/ide/src/base-ui/chart/column/LitChartColumn.ts +++ b/ide/src/base-ui/chart/column/LitChartColumn.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { BaseElement, element } from '../../BaseElement.js'; -import { LitChartColumnConfig } from './LitChartColumnConfig.js'; -import { resizeCanvas } from '../helper.js'; -import { getProbablyTime } from '../../../trace/database/logic-worker/ProcedureLogicWorkerCommon.js'; +import { BaseElement, element } from '../../BaseElement'; +import { LitChartColumnConfig } from './LitChartColumnConfig'; +import { resizeCanvas } from '../helper'; +import { getProbablyTime } from '../../../trace/database/logic-worker/ProcedureLogicWorkerCommon'; class Pillar { obj?: any; diff --git a/ide/src/base-ui/chart/pagenation/PaginationBox.ts b/ide/src/base-ui/chart/pagenation/PaginationBox.ts index eca0285ea..8c455d3af 100644 --- a/ide/src/base-ui/chart/pagenation/PaginationBox.ts +++ b/ide/src/base-ui/chart/pagenation/PaginationBox.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../../BaseElement.js'; +import { BaseElement, element } from '../../BaseElement'; @element('pagination-box') export class PaginationBox extends BaseElement { diff --git a/ide/src/base-ui/chart/pie/LitChartPie.ts b/ide/src/base-ui/chart/pie/LitChartPie.ts index a70f491bf..55d6fe23e 100644 --- a/ide/src/base-ui/chart/pie/LitChartPie.ts +++ b/ide/src/base-ui/chart/pie/LitChartPie.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { resizeCanvas } from '../helper.js'; -import { BaseElement, element } from '../../BaseElement.js'; -import { LitChartPieConfig } from './LitChartPieConfig.js'; -import { isPointIsCircle, pieChartColors, randomRgbColor } from './LitChartPieData.js'; -import { Utils } from '../../../trace/component/trace/base/Utils.js'; +import { resizeCanvas } from '../helper'; +import { BaseElement, element } from '../../BaseElement'; +import { LitChartPieConfig } from './LitChartPieConfig'; +import { isPointIsCircle, pieChartColors, randomRgbColor } from './LitChartPieData'; +import { Utils } from '../../../trace/component/trace/base/Utils'; interface Rectangle { x: number; diff --git a/ide/src/base-ui/checkbox/LitCheckBox.ts b/ide/src/base-ui/checkbox/LitCheckBox.ts index 0e79fea30..e4bede793 100644 --- a/ide/src/base-ui/checkbox/LitCheckBox.ts +++ b/ide/src/base-ui/checkbox/LitCheckBox.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-check-box') export class LitCheckBox extends BaseElement { diff --git a/ide/src/base-ui/checkbox/LitCheckBoxWithText.ts b/ide/src/base-ui/checkbox/LitCheckBoxWithText.ts index cba91f29b..9316e8c8b 100644 --- a/ide/src/base-ui/checkbox/LitCheckBoxWithText.ts +++ b/ide/src/base-ui/checkbox/LitCheckBoxWithText.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; -import { SpCheckDesBox } from '../../trace/component/setting/SpCheckDesBox.js'; +import { BaseElement, element } from '../BaseElement'; +import { SpCheckDesBox } from '../../trace/component/setting/SpCheckDesBox'; @element('lit-check-text') export class LitCheckBoxWithText extends BaseElement { diff --git a/ide/src/base-ui/checkbox/LitCheckGroup.ts b/ide/src/base-ui/checkbox/LitCheckGroup.ts index 7587ee6e4..4385189e7 100644 --- a/ide/src/base-ui/checkbox/LitCheckGroup.ts +++ b/ide/src/base-ui/checkbox/LitCheckGroup.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; -import { LitCheckBox } from './LitCheckBox.js'; +import { BaseElement, element } from '../BaseElement'; +import { LitCheckBox } from './LitCheckBox'; @element('lit-check-group') export class LitCheckGroup extends BaseElement { diff --git a/ide/src/base-ui/drawer/LitDrawer.ts b/ide/src/base-ui/drawer/LitDrawer.ts index 08415d62b..eefa2c307 100644 --- a/ide/src/base-ui/drawer/LitDrawer.ts +++ b/ide/src/base-ui/drawer/LitDrawer.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-drawer') export class LitDrawer extends BaseElement { diff --git a/ide/src/base-ui/headline/lit-headline.ts b/ide/src/base-ui/headline/lit-headline.ts index ed0e7c5dd..0beed234a 100644 --- a/ide/src/base-ui/headline/lit-headline.ts +++ b/ide/src/base-ui/headline/lit-headline.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-headline') export class LitHeadLine extends BaseElement { diff --git a/ide/src/base-ui/icon.svg b/ide/src/base-ui/icon.svg index 5524fca98..7424ce2a8 100644 --- a/ide/src/base-ui/icon.svg +++ b/ide/src/base-ui/icon.svg @@ -475,70 +475,71 @@ - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - + + \ No newline at end of file diff --git a/ide/src/base-ui/icon/LitIcon.ts b/ide/src/base-ui/icon/LitIcon.ts index af2d22fb0..0ef82237c 100644 --- a/ide/src/base-ui/icon/LitIcon.ts +++ b/ide/src/base-ui/icon/LitIcon.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-icon') export class LitIcon extends BaseElement { diff --git a/ide/src/base-ui/menu/LitMainMenu.ts b/ide/src/base-ui/menu/LitMainMenu.ts index 1b6a0ce68..8a6f3760b 100644 --- a/ide/src/base-ui/menu/LitMainMenu.ts +++ b/ide/src/base-ui/menu/LitMainMenu.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; -import './LitMainMenuItem.js'; -import './LitMainMenuGroup.js'; -import { LitMainMenuGroup } from './LitMainMenuGroup.js'; -import { LitMainMenuItem } from './LitMainMenuItem.js'; +import { BaseElement, element } from '../BaseElement'; +import './LitMainMenuItem'; +import './LitMainMenuGroup'; +import { LitMainMenuGroup } from './LitMainMenuGroup'; +import { LitMainMenuItem } from './LitMainMenuItem'; @element('lit-main-menu') export class LitMainMenu extends BaseElement { diff --git a/ide/src/base-ui/menu/LitMainMenuGroup.ts b/ide/src/base-ui/menu/LitMainMenuGroup.ts index 6dcacf8be..b9d0fbedf 100644 --- a/ide/src/base-ui/menu/LitMainMenuGroup.ts +++ b/ide/src/base-ui/menu/LitMainMenuGroup.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-main-menu-group') export class LitMainMenuGroup extends BaseElement { diff --git a/ide/src/base-ui/menu/LitMainMenuItem.ts b/ide/src/base-ui/menu/LitMainMenuItem.ts index 9a1e7793e..fb8939516 100644 --- a/ide/src/base-ui/menu/LitMainMenuItem.ts +++ b/ide/src/base-ui/menu/LitMainMenuItem.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-main-menu-item') export class LitMainMenuItem extends BaseElement { diff --git a/ide/src/base-ui/modal/LitModal.ts b/ide/src/base-ui/modal/LitModal.ts index 7471a369e..4f8800fe1 100644 --- a/ide/src/base-ui/modal/LitModal.ts +++ b/ide/src/base-ui/modal/LitModal.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-modal') export class LitModal extends BaseElement { diff --git a/ide/src/base-ui/popover/LitPopContent.ts b/ide/src/base-ui/popover/LitPopContent.ts index f78382bca..54fe0d502 100644 --- a/ide/src/base-ui/popover/LitPopContent.ts +++ b/ide/src/base-ui/popover/LitPopContent.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-pop-content') export class LitPopContent extends BaseElement { diff --git a/ide/src/base-ui/popover/LitPopover.ts b/ide/src/base-ui/popover/LitPopover.ts index edc824a85..1413e2f56 100644 --- a/ide/src/base-ui/popover/LitPopover.ts +++ b/ide/src/base-ui/popover/LitPopover.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; -import { LitPopContent } from './LitPopContent.js'; -import { LitPopoverTitle } from './LitPopoverTitle.js'; -import { LitRadioGroup } from '../radiobox/LitRadioGroup.js'; -import { LitRadioBox } from '../radiobox/LitRadioBox.js'; -import { LitCheckBox } from '../checkbox/LitCheckBox.js'; -import { LitCheckGroup } from '../checkbox/LitCheckGroup.js'; -import { LitCheckBoxWithText } from '../checkbox/LitCheckBoxWithText.js'; +import { BaseElement, element } from '../BaseElement'; +import { LitPopContent } from './LitPopContent'; +import { LitPopoverTitle } from './LitPopoverTitle'; +import { LitRadioGroup } from '../radiobox/LitRadioGroup'; +import { LitRadioBox } from '../radiobox/LitRadioBox'; +import { LitCheckBox } from '../checkbox/LitCheckBox'; +import { LitCheckGroup } from '../checkbox/LitCheckGroup'; +import { LitCheckBoxWithText } from '../checkbox/LitCheckBoxWithText'; @element('lit-popover') export class LitPopover extends BaseElement { diff --git a/ide/src/base-ui/popover/LitPopoverTitle.ts b/ide/src/base-ui/popover/LitPopoverTitle.ts index fa0d27d83..dde0ecc16 100644 --- a/ide/src/base-ui/popover/LitPopoverTitle.ts +++ b/ide/src/base-ui/popover/LitPopoverTitle.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-popover-title') export class LitPopoverTitle extends BaseElement { diff --git a/ide/src/base-ui/popover/LitPopoverV.ts b/ide/src/base-ui/popover/LitPopoverV.ts index c3a02f89f..f8bf2f9d1 100644 --- a/ide/src/base-ui/popover/LitPopoverV.ts +++ b/ide/src/base-ui/popover/LitPopoverV.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-popover') export class LitPopover extends BaseElement { diff --git a/ide/src/base-ui/progress-bar/LitProgressBar.ts b/ide/src/base-ui/progress-bar/LitProgressBar.ts index c1f195566..bd6050a81 100644 --- a/ide/src/base-ui/progress-bar/LitProgressBar.ts +++ b/ide/src/base-ui/progress-bar/LitProgressBar.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-progress-bar') export class LitProgressBar extends BaseElement { diff --git a/ide/src/base-ui/radiobox/LitRadioBox.ts b/ide/src/base-ui/radiobox/LitRadioBox.ts index 92067fa3a..2b03964c0 100644 --- a/ide/src/base-ui/radiobox/LitRadioBox.ts +++ b/ide/src/base-ui/radiobox/LitRadioBox.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; -import { LitRadioGroup } from './LitRadioGroup.js'; +import { BaseElement, element } from '../BaseElement'; +import { LitRadioGroup } from './LitRadioGroup'; @element('lit-radio') export class LitRadioBox extends BaseElement { diff --git a/ide/src/base-ui/radiobox/LitRadioGroup.ts b/ide/src/base-ui/radiobox/LitRadioGroup.ts index 866477a94..dfa2e280b 100644 --- a/ide/src/base-ui/radiobox/LitRadioGroup.ts +++ b/ide/src/base-ui/radiobox/LitRadioGroup.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; -import { LitRadioBox } from './LitRadioBox.js'; +import { BaseElement, element } from '../BaseElement'; +import { LitRadioBox } from './LitRadioBox'; @element('lit-radio-group') export class LitRadioGroup extends BaseElement { diff --git a/ide/src/base-ui/select/LitAllocationSelect.ts b/ide/src/base-ui/select/LitAllocationSelect.ts index 53f187bde..51ed28370 100644 --- a/ide/src/base-ui/select/LitAllocationSelect.ts +++ b/ide/src/base-ui/select/LitAllocationSelect.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-allocation-select') export class LitAllocationSelect extends BaseElement { diff --git a/ide/src/base-ui/select/LitSelect.ts b/ide/src/base-ui/select/LitSelect.ts index ad6e60f1d..d010c17e3 100644 --- a/ide/src/base-ui/select/LitSelect.ts +++ b/ide/src/base-ui/select/LitSelect.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; -import { selectHtmlStr } from './LitSelectHtml.js'; +import { BaseElement, element } from '../BaseElement'; +import { selectHtmlStr } from './LitSelectHtml'; @element('lit-select') export class LitSelect extends BaseElement { diff --git a/ide/src/base-ui/select/LitSelectOption.ts b/ide/src/base-ui/select/LitSelectOption.ts index 5c7afc8ce..46310bbc6 100644 --- a/ide/src/base-ui/select/LitSelectOption.ts +++ b/ide/src/base-ui/select/LitSelectOption.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { BaseElement } from '../BaseElement.js'; -import '../icon/LitIcon.js'; +import { BaseElement } from '../BaseElement'; +import '../icon/LitIcon'; export class LitSelectOption extends BaseElement { static get observedAttributes() { diff --git a/ide/src/base-ui/select/LitSelectV.ts b/ide/src/base-ui/select/LitSelectV.ts index fd050676e..340b1330e 100644 --- a/ide/src/base-ui/select/LitSelectV.ts +++ b/ide/src/base-ui/select/LitSelectV.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; -import { LitSelectOption } from './LitSelectOption.js'; -import { selectHtmlStr } from './LitSelectHtml.js'; +import { BaseElement, element } from '../BaseElement'; +import { LitSelectOption } from './LitSelectOption'; +import { selectHtmlStr } from './LitSelectHtml'; @element('lit-select-v') export class LitSelectV extends BaseElement { diff --git a/ide/src/base-ui/slider/LitSlider.ts b/ide/src/base-ui/slider/LitSlider.ts index c608bec99..68e8eec62 100644 --- a/ide/src/base-ui/slider/LitSlider.ts +++ b/ide/src/base-ui/slider/LitSlider.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-slider') export class LitSlider extends BaseElement { diff --git a/ide/src/base-ui/switch/lit-switch.ts b/ide/src/base-ui/switch/lit-switch.ts index 98f214e2c..20520b008 100644 --- a/ide/src/base-ui/switch/lit-switch.ts +++ b/ide/src/base-ui/switch/lit-switch.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; +import { BaseElement, element } from '../BaseElement'; @element('lit-switch') export default class LitSwitch extends BaseElement { diff --git a/ide/src/base-ui/table/LitPageTable.ts b/ide/src/base-ui/table/LitPageTable.ts index 5bf5f914b..48b8aec44 100644 --- a/ide/src/base-ui/table/LitPageTable.ts +++ b/ide/src/base-ui/table/LitPageTable.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { LitTableColumn } from './lit-table-column.js'; -import { LitProgressBar } from './../progress-bar/LitProgressBar.js'; -import { BaseElement, element } from '../BaseElement.js'; -import '../utils/Template.js'; -import { TableRowObject } from './TableRowObject.js'; -import { JSONToCSV } from '../utils/CSVFormater.js'; +import { LitTableColumn } from './lit-table-column'; +import { LitProgressBar } from './../progress-bar/LitProgressBar'; +import { BaseElement, element } from '../BaseElement'; +import '../utils/Template'; +import { TableRowObject } from './TableRowObject'; +import { JSONToCSV } from '../utils/CSVFormater'; @element('lit-page-table') export class LitPageTable extends BaseElement { diff --git a/ide/src/base-ui/table/lit-table-column.ts b/ide/src/base-ui/table/lit-table-column.ts index ba00a4d3a..0807bb01a 100644 --- a/ide/src/base-ui/table/lit-table-column.ts +++ b/ide/src/base-ui/table/lit-table-column.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { element } from '../BaseElement.js'; +import { element } from '../BaseElement'; @element('lit-table-column') export class LitTableColumn extends HTMLElement { diff --git a/ide/src/base-ui/table/lit-table-group.ts b/ide/src/base-ui/table/lit-table-group.ts index 700e5a81c..d33649c9a 100644 --- a/ide/src/base-ui/table/lit-table-group.ts +++ b/ide/src/base-ui/table/lit-table-group.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { element } from '../BaseElement.js'; +import { element } from '../BaseElement'; @element('lit-table-group') export class LitTableGroup extends HTMLElement { diff --git a/ide/src/base-ui/table/lit-table.ts b/ide/src/base-ui/table/lit-table.ts index a85f196ed..a71e36461 100644 --- a/ide/src/base-ui/table/lit-table.ts +++ b/ide/src/base-ui/table/lit-table.ts @@ -13,17 +13,17 @@ * limitations under the License. */ -import { LitTableColumn } from './lit-table-column.js'; -import { LitProgressBar } from './../progress-bar/LitProgressBar.js'; -import { element } from '../BaseElement.js'; -import '../utils/Template.js'; -import { TableRowObject } from './TableRowObject.js'; -import { ExcelFormater } from '../utils/ExcelFormater.js'; -import { JSONToCSV } from '../utils/CSVFormater.js'; -import { NodeType } from '../../js-heap/model/DatabaseStruct.js'; -import { ConstructorType } from '../../js-heap/model/UiStruct.js'; -import { LitIcon } from '../icon/LitIcon.js'; -import { JsCpuProfilerStatisticsStruct } from '../../trace/bean/JsStruct.js'; +import { LitTableColumn } from './lit-table-column'; +import { LitProgressBar } from './../progress-bar/LitProgressBar'; +import { element } from '../BaseElement'; +import '../utils/Template'; +import { TableRowObject } from './TableRowObject'; +import { ExcelFormater } from '../utils/ExcelFormater'; +import { JSONToCSV } from '../utils/CSVFormater'; +import { NodeType } from '../../js-heap/model/DatabaseStruct'; +import { ConstructorType } from '../../js-heap/model/UiStruct'; +import { LitIcon } from '../icon/LitIcon'; +import { JsCpuProfilerStatisticsStruct } from '../../trace/bean/JsStruct'; const iconWidth = 20; const iconPadding = 5; @element('lit-table') diff --git a/ide/src/base-ui/tabs/lit-tabpane.ts b/ide/src/base-ui/tabs/lit-tabpane.ts index 358749fdc..d8d744694 100644 --- a/ide/src/base-ui/tabs/lit-tabpane.ts +++ b/ide/src/base-ui/tabs/lit-tabpane.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { BaseElement, element } from '../BaseElement.js'; -import { LitTabs } from './lit-tabs.js'; +import { BaseElement, element } from '../BaseElement'; +import { LitTabs } from './lit-tabs'; @element('lit-tabpane') export class LitTabpane extends BaseElement { diff --git a/ide/src/base-ui/tabs/lit-tabs.ts b/ide/src/base-ui/tabs/lit-tabs.ts index 34ba64b3c..1187d8bc7 100644 --- a/ide/src/base-ui/tabs/lit-tabs.ts +++ b/ide/src/base-ui/tabs/lit-tabs.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { element } from '../BaseElement.js'; -import { LitTabpane } from './lit-tabpane.js'; -import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil.js'; +import { element } from '../BaseElement'; +import { LitTabpane } from './lit-tabpane'; +import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil'; @element('lit-tabs') export class LitTabs extends HTMLElement { diff --git a/ide/src/base-ui/tree/LitTree.ts b/ide/src/base-ui/tree/LitTree.ts index 86ab8286c..a5f9e0495 100644 --- a/ide/src/base-ui/tree/LitTree.ts +++ b/ide/src/base-ui/tree/LitTree.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import './LitTreeNode.js'; -import { BaseElement, element } from '../BaseElement.js'; -import { type LitTreeNode } from './LitTreeNode.js'; +import './LitTreeNode'; +import { BaseElement, element } from '../BaseElement'; +import { type LitTreeNode } from './LitTreeNode'; export interface TreeItemData { key: string; diff --git a/ide/src/base-ui/tree/LitTreeNode.ts b/ide/src/base-ui/tree/LitTreeNode.ts index 748508653..f33ce5193 100644 --- a/ide/src/base-ui/tree/LitTreeNode.ts +++ b/ide/src/base-ui/tree/LitTreeNode.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import '../icon/LitIcon.js'; -import { BaseElement, element } from '../BaseElement.js'; -import { type LitIcon } from '../icon/LitIcon.js'; -import { type TreeItemData } from './LitTree.js'; +import '../icon/LitIcon'; +import { BaseElement, element } from '../BaseElement'; +import { type LitIcon } from '../icon/LitIcon'; +import { type TreeItemData } from './LitTree'; @element('lit-tree-node') export class LitTreeNode extends BaseElement { diff --git a/ide/src/command/Cmd.ts b/ide/src/command/Cmd.ts index 9ce0e28c8..f1ab49b97 100644 --- a/ide/src/command/Cmd.ts +++ b/ide/src/command/Cmd.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { SpRecordTrace } from '../trace/component/SpRecordTrace.js'; -import { CmdConstant } from './CmdConstant.js'; -import { HdcDeviceManager } from '../hdc/HdcDeviceManager.js'; +import { SpRecordTrace } from '../trace/component/SpRecordTrace'; +import { CmdConstant } from './CmdConstant'; +import { HdcDeviceManager } from '../hdc/HdcDeviceManager'; export class Cmd { static CmdSendPostUtils(uri: string, callback: Function, requestData: any) { diff --git a/ide/src/hdc/HdcDeviceManager.ts b/ide/src/hdc/HdcDeviceManager.ts index 6f484b160..3aa0ca9bf 100644 --- a/ide/src/hdc/HdcDeviceManager.ts +++ b/ide/src/hdc/HdcDeviceManager.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { HdcClient } from './hdcclient/HdcClient.js'; -import { UsbTransmissionChannel } from './transmission/UsbTransmissionChannel.js'; -import { HDC_DEVICE_FILTERS } from './common/ConstantType.js'; -import { FormatCommand } from './hdcclient/FormatCommand.js'; -import { log } from '../log/Log.js'; -import { HdcStream } from './hdcclient/HdcStream.js'; -import { HdcCommand } from './hdcclient/HdcCommand.js'; -import { SpRecordTrace } from '../trace/component/SpRecordTrace.js'; -import { DataMessage } from './message/DataMessage.js'; +import { HdcClient } from './hdcclient/HdcClient'; +import { UsbTransmissionChannel } from './transmission/UsbTransmissionChannel'; +import { HDC_DEVICE_FILTERS } from './common/ConstantType'; +import { FormatCommand } from './hdcclient/FormatCommand'; +import { log } from '../log/Log'; +import { HdcStream } from './hdcclient/HdcStream'; +import { HdcCommand } from './hdcclient/HdcCommand'; +import { SpRecordTrace } from '../trace/component/SpRecordTrace'; +import { DataMessage } from './message/DataMessage'; export class HdcDeviceManager { static escapeCharacterDict = { diff --git a/ide/src/hdc/common/Serialize.ts b/ide/src/hdc/common/Serialize.ts index a4201d929..6b912a839 100644 --- a/ide/src/hdc/common/Serialize.ts +++ b/ide/src/hdc/common/Serialize.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { WireType } from '../message/WireType.js'; -import { SessionHandShake } from '../message/SessionHandShake.js'; -import { PayloadProtect } from '../message/PayloadProtect.js'; -import { TransferConfig } from '../message/TransferConfig.js'; -import { TransferPayload } from '../message/TransferPayload.js'; -import { log } from '../../log/Log.js'; +import { WireType } from '../message/WireType'; +import { SessionHandShake } from '../message/SessionHandShake'; +import { PayloadProtect } from '../message/PayloadProtect'; +import { TransferConfig } from '../message/TransferConfig'; +import { TransferPayload } from '../message/TransferPayload'; +import { log } from '../../log/Log'; export class Serialize { static bannerByteLength: number = 8; diff --git a/ide/src/hdc/common/Utils.ts b/ide/src/hdc/common/Utils.ts index 84ba57105..8450eea74 100644 --- a/ide/src/hdc/common/Utils.ts +++ b/ide/src/hdc/common/Utils.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { FormatCommand } from '../hdcclient/FormatCommand.js'; -import { warn } from '../../log/Log.js'; +import { FormatCommand } from '../hdcclient/FormatCommand'; +import { warn } from '../../log/Log'; export class Utils { private static localId = 1; diff --git a/ide/src/hdc/hdcclient/AsyncQueue.ts b/ide/src/hdc/hdcclient/AsyncQueue.ts index 3b2099451..d2ffe40f0 100644 --- a/ide/src/hdc/hdcclient/AsyncQueue.ts +++ b/ide/src/hdc/hdcclient/AsyncQueue.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { DataMessage } from '../message/DataMessage.js'; +import { DataMessage } from '../message/DataMessage'; export class DataMessageQueue { private eleArray: Array; diff --git a/ide/src/hdc/hdcclient/DataListener.ts b/ide/src/hdc/hdcclient/DataListener.ts index b741e1fa2..cc7860b47 100644 --- a/ide/src/hdc/hdcclient/DataListener.ts +++ b/ide/src/hdc/hdcclient/DataListener.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { DataMessage } from '../message/DataMessage.js'; +import { DataMessage } from '../message/DataMessage'; export interface DataListener { createDataMessage(data: DataMessage): void; diff --git a/ide/src/hdc/hdcclient/FormatCommand.ts b/ide/src/hdc/hdcclient/FormatCommand.ts index 46eeab31f..766b470a0 100644 --- a/ide/src/hdc/hdcclient/FormatCommand.ts +++ b/ide/src/hdc/hdcclient/FormatCommand.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { HdcCommand } from './HdcCommand.js'; -import { CMDSTR_FILE_RECV, CMDSTR_FILE_SEND, CMDSTR_SHELL } from '../common/ConstantType.js'; -import { log } from '../../log/Log.js'; +import { HdcCommand } from './HdcCommand'; +import { CMDSTR_FILE_RECV, CMDSTR_FILE_SEND, CMDSTR_SHELL } from '../common/ConstantType'; +import { log } from '../../log/Log'; export class FormatCommand { cmdFlag: number; // uint16_t diff --git a/ide/src/hdc/hdcclient/HdcClient.ts b/ide/src/hdc/hdcclient/HdcClient.ts index 241af4c1a..b82a83795 100644 --- a/ide/src/hdc/hdcclient/HdcClient.ts +++ b/ide/src/hdc/hdcclient/HdcClient.ts @@ -13,21 +13,21 @@ * limitations under the License. */ -import { Serialize } from '../common/Serialize.js'; -import { HdcCommand } from './HdcCommand.js'; -import { Utils } from '../common/Utils.js'; -import { HANDSHAKE_MESSAGE } from '../common/ConstantType.js'; -import { PayloadHead } from '../message/PayloadHead.js'; -import { TransmissionInterface } from '../transmission/TransmissionInterface.js'; -import { DataProcessing } from '../transmission/DataProcessing.js'; -import { DataListener } from './DataListener.js'; -import { DataMessage } from '../message/DataMessage.js'; -import { SessionHandShake } from '../message/SessionHandShake.js'; -import { AuthType } from '../message/AuthType.js'; -import { debug, log } from '../../log/Log.js'; -import { HdcStream } from './HdcStream.js'; -import { toHex16 } from '../common/BaseConversion.js'; -import { USBHead } from '../message/USBHead.js'; +import { Serialize } from '../common/Serialize'; +import { HdcCommand } from './HdcCommand'; +import { Utils } from '../common/Utils'; +import { HANDSHAKE_MESSAGE } from '../common/ConstantType'; +import { PayloadHead } from '../message/PayloadHead'; +import { TransmissionInterface } from '../transmission/TransmissionInterface'; +import { DataProcessing } from '../transmission/DataProcessing'; +import { DataListener } from './DataListener'; +import { DataMessage } from '../message/DataMessage'; +import { SessionHandShake } from '../message/SessionHandShake'; +import { AuthType } from '../message/AuthType'; +import { debug, log } from '../../log/Log'; +import { HdcStream } from './HdcStream'; +import { toHex16 } from '../common/BaseConversion'; +import { USBHead } from '../message/USBHead'; export class HdcClient implements DataListener { // @ts-ignore diff --git a/ide/src/hdc/hdcclient/HdcStream.ts b/ide/src/hdc/hdcclient/HdcStream.ts index 8f2249798..a97a7640f 100644 --- a/ide/src/hdc/hdcclient/HdcStream.ts +++ b/ide/src/hdc/hdcclient/HdcStream.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { DataMessage } from '../message/DataMessage.js'; -import { HdcClient } from './HdcClient.js'; -import { FormatCommand } from './FormatCommand.js'; -import { HdcCommand } from './HdcCommand.js'; -import { Utils } from '../common/Utils.js'; -import { AsyncQueue } from './AsyncQueue.js'; -import { PayloadHead } from '../message/PayloadHead.js'; -import { Serialize } from '../common/Serialize.js'; +import { DataMessage } from '../message/DataMessage'; +import { HdcClient } from './HdcClient'; +import { FormatCommand } from './FormatCommand'; +import { HdcCommand } from './HdcCommand'; +import { Utils } from '../common/Utils'; +import { AsyncQueue } from './AsyncQueue'; +import { PayloadHead } from '../message/PayloadHead'; +import { Serialize } from '../common/Serialize'; export class HdcStream { private dataMessages: AsyncQueue = new AsyncQueue(); diff --git a/ide/src/hdc/message/DataMessage.ts b/ide/src/hdc/message/DataMessage.ts index 811205a35..28894dea8 100644 --- a/ide/src/hdc/message/DataMessage.ts +++ b/ide/src/hdc/message/DataMessage.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { USBHead } from './USBHead.js'; -import { debug, log } from '../../log/Log.js'; -import { PayloadHead } from './PayloadHead.js'; -import { Serialize } from '../common/Serialize.js'; -import { Utils } from '../common/Utils.js'; -import { HdcCommand } from '../hdcclient/HdcCommand.js'; +import { USBHead } from './USBHead'; +import { debug, log } from '../../log/Log'; +import { PayloadHead } from './PayloadHead'; +import { Serialize } from '../common/Serialize'; +import { Utils } from '../common/Utils'; +import { HdcCommand } from '../hdcclient/HdcCommand'; export class DataMessage extends Object { body?: DataView; diff --git a/ide/src/hdc/message/PayloadHead.ts b/ide/src/hdc/message/PayloadHead.ts index cea209a98..46c1c9423 100644 --- a/ide/src/hdc/message/PayloadHead.ts +++ b/ide/src/hdc/message/PayloadHead.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseBean } from './BaseBean.js'; +import { BaseBean } from './BaseBean'; export class PayloadHead extends Object implements BaseBean { private _flag: Array = [0, 0]; //uint8_t ct.c_uint8 * 2 diff --git a/ide/src/hdc/message/PayloadProtect.ts b/ide/src/hdc/message/PayloadProtect.ts index bc5a935df..9b40b2a77 100644 --- a/ide/src/hdc/message/PayloadProtect.ts +++ b/ide/src/hdc/message/PayloadProtect.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseBean } from './BaseBean.js'; +import { BaseBean } from './BaseBean'; export class PayloadProtect extends Object implements BaseBean { // reserve for encrypt and decrypt diff --git a/ide/src/hdc/message/SessionHandShake.ts b/ide/src/hdc/message/SessionHandShake.ts index a256f76c3..ac6093545 100644 --- a/ide/src/hdc/message/SessionHandShake.ts +++ b/ide/src/hdc/message/SessionHandShake.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { AuthType } from './AuthType.js'; -import { HANDSHAKE_MESSAGE } from '../common/ConstantType.js'; -import { BaseBean } from './BaseBean.js'; +import { AuthType } from './AuthType'; +import { HANDSHAKE_MESSAGE } from '../common/ConstantType'; +import { BaseBean } from './BaseBean'; export class SessionHandShake extends Object implements BaseBean { private _banner: string = HANDSHAKE_MESSAGE; // string must first index diff --git a/ide/src/hdc/message/USBHead.ts b/ide/src/hdc/message/USBHead.ts index 1da3cda47..3c60dae02 100644 --- a/ide/src/hdc/message/USBHead.ts +++ b/ide/src/hdc/message/USBHead.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseBean } from './BaseBean.js'; +import { BaseBean } from './BaseBean'; export class USBHead extends Object implements BaseBean { private _flag: number[]; // uint8_t 'flag', ct.c_uint8 * 2 flag[2] 2 diff --git a/ide/src/hdc/transmission/DataProcessing.ts b/ide/src/hdc/transmission/DataProcessing.ts index 0b7d6491f..446b7c455 100644 --- a/ide/src/hdc/transmission/DataProcessing.ts +++ b/ide/src/hdc/transmission/DataProcessing.ts @@ -13,17 +13,17 @@ * limitations under the License. */ -import { TransmissionInterface } from './TransmissionInterface.js'; -import { PACKET_FLAG, USB_PACKET_FLAG } from '../common/ConstantType.js'; -import { USBHead } from '../message/USBHead.js'; -import { DataMessage } from '../message/DataMessage.js'; -import { DataListener } from '../hdcclient/DataListener.js'; -import { PayloadProtect } from '../message/PayloadProtect.js'; -import { Serialize } from '../common/Serialize.js'; -import { PayloadHead } from '../message/PayloadHead.js'; -import { UsbProtocolOption } from '../hdcclient/UsbProtocolOption.js'; -import { toHex16 } from '../common/BaseConversion.js'; -import { error, log } from '../../log/Log.js'; +import { TransmissionInterface } from './TransmissionInterface'; +import { PACKET_FLAG, USB_PACKET_FLAG } from '../common/ConstantType'; +import { USBHead } from '../message/USBHead'; +import { DataMessage } from '../message/DataMessage'; +import { DataListener } from '../hdcclient/DataListener'; +import { PayloadProtect } from '../message/PayloadProtect'; +import { Serialize } from '../common/Serialize'; +import { PayloadHead } from '../message/PayloadHead'; +import { UsbProtocolOption } from '../hdcclient/UsbProtocolOption'; +import { toHex16 } from '../common/BaseConversion'; +import { error, log } from '../../log/Log'; export class DataProcessing { private readonly transmissionChannel: TransmissionInterface; diff --git a/ide/src/hdc/transmission/UsbTransmissionChannel.ts b/ide/src/hdc/transmission/UsbTransmissionChannel.ts index 976517912..c1a3798df 100644 --- a/ide/src/hdc/transmission/UsbTransmissionChannel.ts +++ b/ide/src/hdc/transmission/UsbTransmissionChannel.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { TransmissionInterface } from './TransmissionInterface.js'; -import { info } from '../../log/Log.js'; -import { HDC_DEVICE_FILTER } from '../common/ConstantType.js'; +import { TransmissionInterface } from './TransmissionInterface'; +import { info } from '../../log/Log'; +import { HDC_DEVICE_FILTER } from '../common/ConstantType'; export interface matchingUsbDevice { configurationValue: number; diff --git a/ide/src/index.ts b/ide/src/index.ts new file mode 100644 index 000000000..e704a70af --- /dev/null +++ b/ide/src/index.ts @@ -0,0 +1,3 @@ +import "./trace/SpApplication"; +import {SpApplication} from "./trace/SpApplication"; +document.body.innerHTML = ""; \ No newline at end of file diff --git a/ide/src/js-heap/HeapDataInterface.ts b/ide/src/js-heap/HeapDataInterface.ts index 9c3ac75d6..d5afab0a0 100644 --- a/ide/src/js-heap/HeapDataInterface.ts +++ b/ide/src/js-heap/HeapDataInterface.ts @@ -13,16 +13,16 @@ * limitations under the License. */ -import { HeapLoader } from './logic/HeapLoader.js'; +import { HeapLoader } from './logic/HeapLoader'; import { AllocationFunction, ConstructorComparison, ConstructorItem, ConstructorType, FileInfo, -} from './model/UiStruct.js'; -import { HeapNodeToConstructorItem } from './utils/Utils.js'; -import { FileStruct, HeapSample, HeapTraceFunctionInfo } from './model/DatabaseStruct.js'; +} from './model/UiStruct'; +import { HeapNodeToConstructorItem } from './utils/Utils'; +import { FileStruct, HeapSample, HeapTraceFunctionInfo } from './model/DatabaseStruct'; export interface ParseListener { parseDone(fileModule: Array): void; diff --git a/ide/src/js-heap/LoadDatabase.ts b/ide/src/js-heap/LoadDatabase.ts index af3c2d317..0357eae83 100644 --- a/ide/src/js-heap/LoadDatabase.ts +++ b/ide/src/js-heap/LoadDatabase.ts @@ -12,10 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { HeapDataInterface, ParseListener } from './HeapDataInterface.js'; -import { AllocationFunction, FileType } from './model/UiStruct.js'; -import { getTimeForLog } from './utils/Utils.js'; -import { HeapNode, FileStruct } from './model/DatabaseStruct.js'; +import { HeapDataInterface, ParseListener } from './HeapDataInterface'; +import { AllocationFunction, FileType } from './model/UiStruct'; +import { getTimeForLog } from './utils/Utils'; +import { HeapNode, FileStruct } from './model/DatabaseStruct'; import { queryHeapFile, queryHeapInfo, @@ -25,8 +25,8 @@ import { queryHeapTraceNode, queryHeapSample, queryHeapString, -} from '../trace/database/SqlLite.js'; -import { info } from '../log/Log.js'; +} from '../trace/database/SqlLite'; +import { info } from '../log/Log'; export class LoadDatabase { private static loadDB: LoadDatabase; diff --git a/ide/src/js-heap/logic/Allocation.ts b/ide/src/js-heap/logic/Allocation.ts index a910d2473..72a1733a1 100644 --- a/ide/src/js-heap/logic/Allocation.ts +++ b/ide/src/js-heap/logic/Allocation.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { AllocationFunction } from '../model/UiStruct.js'; -import { FileStruct, HeapTraceFunctionInfo } from '../model/DatabaseStruct.js'; +import { AllocationFunction } from '../model/UiStruct'; +import { FileStruct, HeapTraceFunctionInfo } from '../model/DatabaseStruct'; export class AllocationLogic { private fileStruct: FileStruct; diff --git a/ide/src/js-heap/logic/HeapLoader.ts b/ide/src/js-heap/logic/HeapLoader.ts index 3bfcbb69d..920d6e2e3 100644 --- a/ide/src/js-heap/logic/HeapLoader.ts +++ b/ide/src/js-heap/logic/HeapLoader.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { AllocationLogic } from './Allocation.js'; -import { AllocationFunction, ConstructorComparison, ConstructorItem, ConstructorType } from '../model/UiStruct.js'; +import { AllocationLogic } from './Allocation'; +import { AllocationFunction, ConstructorComparison, ConstructorItem, ConstructorType } from '../model/UiStruct'; import { DetachedNessState, EdgeType, @@ -24,8 +24,8 @@ import { HeapSample, HeapTraceFunctionInfo, NodeType, -} from '../model/DatabaseStruct.js'; -import { HeapNodeToConstructorItem } from '../utils/Utils.js'; +} from '../model/DatabaseStruct'; +import { HeapNodeToConstructorItem } from '../utils/Utils'; const BASE_SYSTEM_DISTANCE = 100000000; const CAN_BE_QUERIED = 1; diff --git a/ide/src/js-heap/model/DatabaseStruct.ts b/ide/src/js-heap/model/DatabaseStruct.ts index 4112d19b0..8751f9286 100644 --- a/ide/src/js-heap/model/DatabaseStruct.ts +++ b/ide/src/js-heap/model/DatabaseStruct.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { HeapLoader } from '../logic/HeapLoader.js'; -import { AllocationFunction, FileInfo } from './UiStruct.js'; +import { HeapLoader } from '../logic/HeapLoader'; +import { AllocationFunction, FileInfo } from './UiStruct'; export enum EdgeType { CONTEXT = 0, diff --git a/ide/src/js-heap/model/UiStruct.ts b/ide/src/js-heap/model/UiStruct.ts index 02555a42a..2c27bad7c 100644 --- a/ide/src/js-heap/model/UiStruct.ts +++ b/ide/src/js-heap/model/UiStruct.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { HeapDataInterface } from '../HeapDataInterface.js'; -import { EdgeType, NodeType } from './DatabaseStruct.js'; +import { HeapDataInterface } from '../HeapDataInterface'; +import { EdgeType, NodeType } from './DatabaseStruct'; const ROW_TYPE = 'js-memory'; export enum FileType { SNAPSHOT, diff --git a/ide/src/js-heap/utils/Utils.ts b/ide/src/js-heap/utils/Utils.ts index 462a9b0e6..3f0f947c2 100644 --- a/ide/src/js-heap/utils/Utils.ts +++ b/ide/src/js-heap/utils/Utils.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { HeapNode } from '../model/DatabaseStruct.js'; -import { ConstructorComparison } from '../model/UiStruct.js'; +import { HeapNode } from '../model/DatabaseStruct'; +import { ConstructorComparison } from '../model/UiStruct'; export function HeapNodeToConstructorItem(node: HeapNode): ConstructorComparison { let constructor = new ConstructorComparison(); diff --git a/ide/src/statistics/util/SpStatisticsHttpUtil.ts b/ide/src/statistics/util/SpStatisticsHttpUtil.ts index 0273215f4..1b88dbc8e 100644 --- a/ide/src/statistics/util/SpStatisticsHttpUtil.ts +++ b/ide/src/statistics/util/SpStatisticsHttpUtil.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BurialPointRequestBody } from './SpStatisticsHttpBean.js'; +import { BurialPointRequestBody } from './SpStatisticsHttpBean'; export class SpStatisticsHttpUtil { static requestServerInfo: string = ''; diff --git a/ide/src/trace/SpApplication.ts b/ide/src/trace/SpApplication.ts index 3c4e3cae5..8ec0a2a9a 100644 --- a/ide/src/trace/SpApplication.ts +++ b/ide/src/trace/SpApplication.ts @@ -13,50 +13,50 @@ * limitations under the License. */ -import { BaseElement, element } from '../base-ui/BaseElement.js'; -import '../base-ui/menu/LitMainMenu.js'; -import '../base-ui/icon/LitIcon.js'; -import { SpMetrics } from './component/SpMetrics.js'; -import { SpHelp } from './component/SpHelp.js'; -import './component/SpHelp.js'; -import { SpQuerySQL } from './component/SpQuerySQL.js'; -import './component/SpQuerySQL.js'; -import { SpSystemTrace } from './component/SpSystemTrace.js'; -import { LitMainMenu, MenuItem } from '../base-ui/menu/LitMainMenu.js'; -import { SpInfoAndStats } from './component/SpInfoAndStas.js'; -import '../base-ui/progress-bar/LitProgressBar.js'; -import { LitProgressBar } from '../base-ui/progress-bar/LitProgressBar.js'; -import { SpRecordTrace } from './component/SpRecordTrace.js'; -import { SpWelcomePage } from './component/SpWelcomePage.js'; -import { LitSearch } from './component/trace/search/Search.js'; -import { DbPool, queryExistFtrace, queryTraceType, threadPool } from './database/SqlLite.js'; -import './component/trace/search/Search.js'; -import './component/SpWelcomePage.js'; -import './component/SpSystemTrace.js'; -import './component/SpRecordTrace.js'; -import './component/SpMetrics.js'; -import './component/SpInfoAndStas.js'; -import './component/trace/base/TraceRow.js'; -import './component/schedulingAnalysis/SpSchedulingAnalysis.js'; -import { info, log } from '../log/Log.js'; -import { LitMainMenuGroup } from '../base-ui/menu/LitMainMenuGroup.js'; -import { LitMainMenuItem } from '../base-ui/menu/LitMainMenuItem.js'; -import { LitIcon } from '../base-ui/icon/LitIcon.js'; -import { Cmd } from '../command/Cmd.js'; -import { TraceRow } from './component/trace/base/TraceRow.js'; -import { SpSchedulingAnalysis } from './component/schedulingAnalysis/SpSchedulingAnalysis.js'; -import './component/trace/base/TraceRowConfig.js'; -import { TraceRowConfig } from './component/trace/base/TraceRowConfig.js'; -import { ColorUtils } from './component/trace/base/ColorUtils.js'; -import { SpStatisticsHttpUtil } from '../statistics/util/SpStatisticsHttpUtil.js'; -import { FlagsConfig, SpFlags } from './component/SpFlags.js'; -import './component/SpFlags.js'; -import './component/trace/base/CustomThemeColor.js'; -import { CustomThemeColor, Theme } from './component/trace/base/CustomThemeColor.js'; -import { convertPool } from './database/Convert.js'; -import { LongTraceDBUtils } from './database/LongTraceDBUtils.js'; -import { type SpKeyboard } from './component/SpKeyboard.js'; -import './component/SpKeyboard.js'; +import { BaseElement, element } from '../base-ui/BaseElement'; +import '../base-ui/menu/LitMainMenu'; +import '../base-ui/icon/LitIcon'; +import { SpMetrics } from './component/SpMetrics'; +import { SpHelp } from './component/SpHelp'; +import './component/SpHelp'; +import { SpQuerySQL } from './component/SpQuerySQL'; +import './component/SpQuerySQL'; +import { SpSystemTrace } from './component/SpSystemTrace'; +import { LitMainMenu, MenuItem } from '../base-ui/menu/LitMainMenu'; +import { SpInfoAndStats } from './component/SpInfoAndStas'; +import '../base-ui/progress-bar/LitProgressBar'; +import { LitProgressBar } from '../base-ui/progress-bar/LitProgressBar'; +import { SpRecordTrace } from './component/SpRecordTrace'; +import { SpWelcomePage } from './component/SpWelcomePage'; +import { LitSearch } from './component/trace/search/Search'; +import { DbPool, queryExistFtrace, queryTraceType, threadPool } from './database/SqlLite'; +import './component/trace/search/Search'; +import './component/SpWelcomePage'; +import './component/SpSystemTrace'; +import './component/SpRecordTrace'; +import './component/SpMetrics'; +import './component/SpInfoAndStas'; +import './component/trace/base/TraceRow'; +import './component/schedulingAnalysis/SpSchedulingAnalysis'; +import { info, log } from '../log/Log'; +import { LitMainMenuGroup } from '../base-ui/menu/LitMainMenuGroup'; +import { LitMainMenuItem } from '../base-ui/menu/LitMainMenuItem'; +import { LitIcon } from '../base-ui/icon/LitIcon'; +import { Cmd } from '../command/Cmd'; +import { TraceRow } from './component/trace/base/TraceRow'; +import { SpSchedulingAnalysis } from './component/schedulingAnalysis/SpSchedulingAnalysis'; +import './component/trace/base/TraceRowConfig'; +import { TraceRowConfig } from './component/trace/base/TraceRowConfig'; +import { ColorUtils } from './component/trace/base/ColorUtils'; +import { SpStatisticsHttpUtil } from '../statistics/util/SpStatisticsHttpUtil'; +import { FlagsConfig, SpFlags } from './component/SpFlags'; +import './component/SpFlags'; +import './component/trace/base/CustomThemeColor'; +import { CustomThemeColor, Theme } from './component/trace/base/CustomThemeColor'; +import { convertPool } from './database/Convert'; +import { LongTraceDBUtils } from './database/LongTraceDBUtils'; +import { type SpKeyboard } from './component/SpKeyboard'; +import './component/SpKeyboard'; @element('sp-application') export class SpApplication extends BaseElement { diff --git a/ide/src/trace/bean/AbilityMonitor.ts b/ide/src/trace/bean/AbilityMonitor.ts index 8134d316c..668191d25 100644 --- a/ide/src/trace/bean/AbilityMonitor.ts +++ b/ide/src/trace/bean/AbilityMonitor.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { CompareStruct } from '../component/trace/sheet/SheetUtils.js'; +import { CompareStruct } from '../component/trace/sheet/SheetUtils'; export class SystemCpuSummary { startTime: number = -1; diff --git a/ide/src/trace/bean/BaseStruct.ts b/ide/src/trace/bean/BaseStruct.ts index 303a1b391..040c3300a 100644 --- a/ide/src/trace/bean/BaseStruct.ts +++ b/ide/src/trace/bean/BaseStruct.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { Rect } from '../component/trace/timer-shaft/Rect.js'; +import { Rect } from '../component/trace/timer-shaft/Rect'; export class BaseStruct { frame: Rect | undefined; diff --git a/ide/src/trace/bean/BoxSelection.ts b/ide/src/trace/bean/BoxSelection.ts index 9301a08f0..d840ebc38 100644 --- a/ide/src/trace/bean/BoxSelection.ts +++ b/ide/src/trace/bean/BoxSelection.ts @@ -13,16 +13,16 @@ * limitations under the License. */ -import { CpuFreqLimitsStruct } from '../database/ui-worker/ProcedureWorkerCpuFreqLimits.js'; -import { ClockStruct } from '../database/ui-worker/ProcedureWorkerClock.js'; -import { IrqStruct } from '../database/ui-worker/ProcedureWorkerIrq.js'; -import { FuncStruct } from '../database/ui-worker/ProcedureWorkerFunc.js'; -import { FrameDynamicStruct } from '../database/ui-worker/ProcedureWorkerFrameDynamic.js'; -import { FrameAnimationStruct } from '../database/ui-worker/ProcedureWorkerFrameAnimation.js'; -import { FrameSpacingStruct } from '../database/ui-worker/ProcedureWorkerFrameSpacing.js'; -import { JsCpuProfilerChartFrame } from './JsStruct.js'; -import { LogStruct } from '../database/ui-worker/ProcedureWorkerLog.js'; -import { HiSysEventStruct } from '../database/ui-worker/ProcedureWorkerHiSysEvent.js'; +import { CpuFreqLimitsStruct } from '../database/ui-worker/ProcedureWorkerCpuFreqLimits'; +import { ClockStruct } from '../database/ui-worker/ProcedureWorkerClock'; +import { IrqStruct } from '../database/ui-worker/ProcedureWorkerIrq'; +import { FuncStruct } from '../database/ui-worker/ProcedureWorkerFunc'; +import { FrameDynamicStruct } from '../database/ui-worker/ProcedureWorkerFrameDynamic'; +import { FrameAnimationStruct } from '../database/ui-worker/ProcedureWorkerFrameAnimation'; +import { FrameSpacingStruct } from '../database/ui-worker/ProcedureWorkerFrameSpacing'; +import { JsCpuProfilerChartFrame } from './JsStruct'; +import { LogStruct } from '../database/ui-worker/ProcedureWorkerLog'; +import { HiSysEventStruct } from '../database/ui-worker/ProcedureWorkerHiSysEvent'; export class SelectionParam { recordStartNs: number = 0; diff --git a/ide/src/trace/bean/CpuFreqStruct.ts b/ide/src/trace/bean/CpuFreqStruct.ts index eb76553d0..fe4545185 100644 --- a/ide/src/trace/bean/CpuFreqStruct.ts +++ b/ide/src/trace/bean/CpuFreqStruct.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { ColorUtils } from '../component/trace/base/ColorUtils.js'; -import { BaseStruct } from './BaseStruct.js'; +import { ColorUtils } from '../component/trace/base/ColorUtils'; +import { BaseStruct } from './BaseStruct'; export class CpuFreqStruct extends BaseStruct { static maxFreq: number = 0; diff --git a/ide/src/trace/bean/CpuStruct.ts b/ide/src/trace/bean/CpuStruct.ts index 5a6752cf8..09218cb4c 100644 --- a/ide/src/trace/bean/CpuStruct.ts +++ b/ide/src/trace/bean/CpuStruct.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ColorUtils } from '../component/trace/base/ColorUtils.js'; -import { BaseStruct } from './BaseStruct.js'; -import { WakeupBean } from './WakeupBean.js'; +import { ColorUtils } from '../component/trace/base/ColorUtils'; +import { BaseStruct } from './BaseStruct'; +import { WakeupBean } from './WakeupBean'; export class CpuStruct extends BaseStruct { static cpuCount: number; //最大cpu数量 diff --git a/ide/src/trace/bean/EbpfStruct.ts b/ide/src/trace/bean/EbpfStruct.ts index 3bd187e9e..992dab3f9 100644 --- a/ide/src/trace/bean/EbpfStruct.ts +++ b/ide/src/trace/bean/EbpfStruct.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { PerfLevelStruct } from './PerfProfile.js'; +import { PerfLevelStruct } from './PerfProfile'; export class CallTreeLevelStruct extends PerfLevelStruct { typeId?: number; diff --git a/ide/src/trace/bean/FpsStruct.ts b/ide/src/trace/bean/FpsStruct.ts index bd705aed9..0a3b98abb 100644 --- a/ide/src/trace/bean/FpsStruct.ts +++ b/ide/src/trace/bean/FpsStruct.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { Rect } from '../component/trace/timer-shaft/Rect.js'; -import { BaseStruct } from './BaseStruct.js'; +import { Rect } from '../component/trace/timer-shaft/Rect'; +import { BaseStruct } from './BaseStruct'; -import { ns2x } from '../component/trace/TimerShaftElement.js'; +import { ns2x } from '../component/trace/TimerShaftElement'; export class FpsStruct extends BaseStruct { static maxFps: number = 0; diff --git a/ide/src/trace/bean/FrameChartStruct.ts b/ide/src/trace/bean/FrameChartStruct.ts index 3841acb38..2e8b2c883 100644 --- a/ide/src/trace/bean/FrameChartStruct.ts +++ b/ide/src/trace/bean/FrameChartStruct.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { SpApplication } from '../SpApplication.js'; -import { Rect } from '../component/trace/timer-shaft/Rect.js'; -import { warn } from '../../log/Log.js'; -import { BaseStruct, drawString } from '../database/ui-worker/ProcedureWorkerCommon.js'; +import { SpApplication } from '../SpApplication'; +import { Rect } from '../component/trace/timer-shaft/Rect'; +import { warn } from '../../log/Log'; +import { BaseStruct, drawString } from '../database/ui-worker/ProcedureWorkerCommon'; const padding: number = 1; const rectHeight = 20; diff --git a/ide/src/trace/bean/FuncStruct.ts b/ide/src/trace/bean/FuncStruct.ts index ab073cd3a..399e9b90f 100644 --- a/ide/src/trace/bean/FuncStruct.ts +++ b/ide/src/trace/bean/FuncStruct.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { BaseStruct } from './BaseStruct.js'; -import { Rect } from '../component/trace/timer-shaft/Rect.js'; -import { ColorUtils } from '../component/trace/base/ColorUtils.js'; -import { drawString } from '../database/ui-worker/ProcedureWorkerCommon.js'; +import { BaseStruct } from './BaseStruct'; +import { Rect } from '../component/trace/timer-shaft/Rect'; +import { ColorUtils } from '../component/trace/base/ColorUtils'; +import { drawString } from '../database/ui-worker/ProcedureWorkerCommon'; export class FuncStruct extends BaseStruct { static hoverFuncStruct: FuncStruct | undefined; diff --git a/ide/src/trace/bean/HeapStruct.ts b/ide/src/trace/bean/HeapStruct.ts index db3d89de9..74a03ee30 100644 --- a/ide/src/trace/bean/HeapStruct.ts +++ b/ide/src/trace/bean/HeapStruct.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseStruct } from './BaseStruct.js'; -import { ns2x } from '../component/trace/TimerShaftElement.js'; -import { Rect } from '../component/trace/timer-shaft/Rect.js'; +import { BaseStruct } from './BaseStruct'; +import { ns2x } from '../component/trace/TimerShaftElement'; +import { Rect } from '../component/trace/timer-shaft/Rect'; export class HeapStruct extends BaseStruct { static hoverHeapStruct: HeapStruct | undefined; diff --git a/ide/src/trace/bean/JanksStruct.ts b/ide/src/trace/bean/JanksStruct.ts index f0367b201..1ba1592cb 100644 --- a/ide/src/trace/bean/JanksStruct.ts +++ b/ide/src/trace/bean/JanksStruct.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseStruct } from './BaseStruct.js'; +import { BaseStruct } from './BaseStruct'; export class JanksStruct extends BaseStruct { static hoverJankStruct: JanksStruct | undefined; diff --git a/ide/src/trace/bean/JsStruct.ts b/ide/src/trace/bean/JsStruct.ts index e2a42f2d1..a94bc0204 100644 --- a/ide/src/trace/bean/JsStruct.ts +++ b/ide/src/trace/bean/JsStruct.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { SampleType } from '../database/logic-worker/ProcedureLogicWorkerJsCpuProfiler.js'; +import { SampleType } from '../database/logic-worker/ProcedureLogicWorkerJsCpuProfiler'; const ROW_TYPE = 'cpu-profiler'; export class JsCpuProfilerUIStruct { name: string; diff --git a/ide/src/trace/bean/NativeHook.ts b/ide/src/trace/bean/NativeHook.ts index e5a617fce..bda0b664a 100644 --- a/ide/src/trace/bean/NativeHook.ts +++ b/ide/src/trace/bean/NativeHook.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { Utils } from '../component/trace/base/Utils.js'; -import { ChartStruct } from '../bean/FrameChartStruct.js'; +import { Utils } from '../component/trace/base/Utils'; +import { ChartStruct } from '../bean/FrameChartStruct'; export class NativeHookStatistics { eventId: number = 0; diff --git a/ide/src/trace/bean/PerfProfile.ts b/ide/src/trace/bean/PerfProfile.ts index d8293e94d..8e067db57 100644 --- a/ide/src/trace/bean/PerfProfile.ts +++ b/ide/src/trace/bean/PerfProfile.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ChartStruct } from '../bean/FrameChartStruct.js'; +import { ChartStruct } from '../bean/FrameChartStruct'; export class PerfFile { path: string = ''; diff --git a/ide/src/trace/bean/ProcessMemStruct.ts b/ide/src/trace/bean/ProcessMemStruct.ts index ce71a2205..6e733e483 100644 --- a/ide/src/trace/bean/ProcessMemStruct.ts +++ b/ide/src/trace/bean/ProcessMemStruct.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { BaseStruct } from './BaseStruct.js'; -import { ColorUtils } from '../component/trace/base/ColorUtils.js'; +import { BaseStruct } from './BaseStruct'; +import { ColorUtils } from '../component/trace/base/ColorUtils'; export class ProcessMemStruct extends BaseStruct { static hoverProcessMemStruct: ProcessMemStruct | undefined; diff --git a/ide/src/trace/bean/ProcessStruct.ts b/ide/src/trace/bean/ProcessStruct.ts index ba70e89fe..94a36c613 100644 --- a/ide/src/trace/bean/ProcessStruct.ts +++ b/ide/src/trace/bean/ProcessStruct.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ColorUtils } from '../component/trace/base/ColorUtils.js'; -import { BaseStruct } from './BaseStruct.js'; -import { CpuStruct } from '../database/ui-worker/ProcedureWorkerCPU.js'; +import { ColorUtils } from '../component/trace/base/ColorUtils'; +import { BaseStruct } from './BaseStruct'; +import { CpuStruct } from '../database/ui-worker/ProcedureWorkerCPU'; const padding = 1; diff --git a/ide/src/trace/bean/ThreadStruct.ts b/ide/src/trace/bean/ThreadStruct.ts index 59e8a75fa..2dc38b5bc 100644 --- a/ide/src/trace/bean/ThreadStruct.ts +++ b/ide/src/trace/bean/ThreadStruct.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseStruct } from './BaseStruct.js'; -import { Utils } from '../component/trace/base/Utils.js'; -import { drawString } from '../database/ui-worker/ProcedureWorkerCommon.js'; +import { BaseStruct } from './BaseStruct'; +import { Utils } from '../component/trace/base/Utils'; +import { drawString } from '../database/ui-worker/ProcedureWorkerCommon'; const padding = 1; diff --git a/ide/src/trace/component/SpFlags.ts b/ide/src/trace/component/SpFlags.ts index c5ece3035..36775d0ef 100644 --- a/ide/src/trace/component/SpFlags.ts +++ b/ide/src/trace/component/SpFlags.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../../base-ui/BaseElement.js'; +import { BaseElement, element } from '../../base-ui/BaseElement'; @element('sp-flags') export class SpFlags extends BaseElement { diff --git a/ide/src/trace/component/SpHelp.ts b/ide/src/trace/component/SpHelp.ts index 89e711aa9..63c247435 100644 --- a/ide/src/trace/component/SpHelp.ts +++ b/ide/src/trace/component/SpHelp.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { BaseElement, element } from '../../base-ui/BaseElement.js'; -import { LitMainMenuGroup } from '../../base-ui/menu/LitMainMenuGroup.js'; -import { LitMainMenu, MenuItem } from '../../base-ui/menu/LitMainMenu.js'; +import { BaseElement, element } from '../../base-ui/BaseElement'; +import { LitMainMenuGroup } from '../../base-ui/menu/LitMainMenuGroup'; +import { LitMainMenu, MenuItem } from '../../base-ui/menu/LitMainMenu'; import { LitMainMenuItem } from '../../base-ui/menu/LitMainMenuItem'; -import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil.js'; +import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil'; @element('sp-help') export class SpHelp extends BaseElement { diff --git a/ide/src/trace/component/SpInfoAndStas.ts b/ide/src/trace/component/SpInfoAndStas.ts index 5d312a750..987d7b544 100644 --- a/ide/src/trace/component/SpInfoAndStas.ts +++ b/ide/src/trace/component/SpInfoAndStas.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { BaseElement, element } from '../../base-ui/BaseElement.js'; -import { querySelectTraceStats, queryTraceMetaData } from '../database/SqlLite.js'; -import { LitTable } from '../../base-ui/table/lit-table.js'; -import '../../base-ui/table/lit-table.js'; -import { info } from '../../log/Log.js'; -import { LitProgressBar } from '../../base-ui/progress-bar/LitProgressBar.js'; +import { BaseElement, element } from '../../base-ui/BaseElement'; +import { querySelectTraceStats, queryTraceMetaData } from '../database/SqlLite'; +import { LitTable } from '../../base-ui/table/lit-table'; +import '../../base-ui/table/lit-table'; +import { info } from '../../log/Log'; +import { LitProgressBar } from '../../base-ui/progress-bar/LitProgressBar'; @element('sp-info-and-stats') export class SpInfoAndStats extends BaseElement { diff --git a/ide/src/trace/component/SpKeyboard.ts b/ide/src/trace/component/SpKeyboard.ts index 45a30f51a..37101379a 100644 --- a/ide/src/trace/component/SpKeyboard.ts +++ b/ide/src/trace/component/SpKeyboard.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../../base-ui/BaseElement.js'; +import { BaseElement, element } from '../../base-ui/BaseElement'; @element('sp-keyboard') export class SpKeyboard extends BaseElement { initElements(): void { diff --git a/ide/src/trace/component/SpMetrics.ts b/ide/src/trace/component/SpMetrics.ts index 0a4122505..6419f53d1 100644 --- a/ide/src/trace/component/SpMetrics.ts +++ b/ide/src/trace/component/SpMetrics.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../base-ui/BaseElement.js'; +import { BaseElement, element } from '../../base-ui/BaseElement'; -import { queryMetric } from '../database/SqlLite.js'; +import { queryMetric } from '../database/SqlLite'; -import '../../base-ui/table/lit-table.js'; -import { LitProgressBar } from '../../base-ui/progress-bar/LitProgressBar.js'; -import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil.js'; +import '../../base-ui/table/lit-table'; +import { LitProgressBar } from '../../base-ui/progress-bar/LitProgressBar'; +import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil'; @element('sp-metrics') export class SpMetrics extends BaseElement { diff --git a/ide/src/trace/component/SpQuerySQL.ts b/ide/src/trace/component/SpQuerySQL.ts index 64ef9b8d9..324482715 100644 --- a/ide/src/trace/component/SpQuerySQL.ts +++ b/ide/src/trace/component/SpQuerySQL.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { BaseElement, element } from '../../base-ui/BaseElement.js'; -import { queryCustomizeSelect } from '../database/SqlLite.js'; -import { LitTable } from '../../base-ui/table/lit-table.js'; -import '../../base-ui/table/lit-table.js'; -import { LitTableColumn } from '../../base-ui/table/lit-table-column.js'; -import { info } from '../../log/Log.js'; -import { LitProgressBar } from '../../base-ui/progress-bar/LitProgressBar.js'; -import { PageNation } from '../../base-ui/chart/pagenation/PageNation.js'; -import { PaginationBox } from '../../base-ui/chart/pagenation/PaginationBox.js'; -import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil.js'; -import { getAllSql } from './trace/base/CommonSql.js'; -import { LitIcon } from '../../base-ui/icon/LitIcon.js'; +import { BaseElement, element } from '../../base-ui/BaseElement'; +import { queryCustomizeSelect } from '../database/SqlLite'; +import { LitTable } from '../../base-ui/table/lit-table'; +import '../../base-ui/table/lit-table'; +import { LitTableColumn } from '../../base-ui/table/lit-table-column'; +import { info } from '../../log/Log'; +import { LitProgressBar } from '../../base-ui/progress-bar/LitProgressBar'; +import { PageNation } from '../../base-ui/chart/pagenation/PageNation'; +import { PaginationBox } from '../../base-ui/chart/pagenation/PaginationBox'; +import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil'; +import { getAllSql } from './trace/base/CommonSql'; +import { LitIcon } from '../../base-ui/icon/LitIcon'; @element('sp-query-sql') export class SpQuerySQL extends BaseElement { diff --git a/ide/src/trace/component/SpRecordTrace.ts b/ide/src/trace/component/SpRecordTrace.ts index bd4190c25..dc04881a2 100644 --- a/ide/src/trace/component/SpRecordTrace.ts +++ b/ide/src/trace/component/SpRecordTrace.ts @@ -13,17 +13,17 @@ * limitations under the License. */ -import { BaseElement, element } from '../../base-ui/BaseElement.js'; -import '../../base-ui/popover/LitPopover.js'; -import '../../base-ui/button/LitButton.js'; -import { LitMainMenuGroup } from '../../base-ui/menu/LitMainMenuGroup.js'; -import { LitMainMenuItem } from '../../base-ui/menu/LitMainMenuItem.js'; -import { SpRecordSetting } from './setting/SpRecordSetting.js'; -import { LitMainMenu, MenuGroup, MenuItem } from '../../base-ui/menu/LitMainMenu.js'; -import { SpProbesConfig } from './setting/SpProbesConfig.js'; -import { SpTraceCommand } from './setting/SpTraceCommand.js'; -import { FlagsConfig } from './SpFlags.js'; -import LitSwitch from '../../base-ui/switch/lit-switch.js'; +import { BaseElement, element } from '../../base-ui/BaseElement'; +import '../../base-ui/popover/LitPopover'; +import '../../base-ui/button/LitButton'; +import { LitMainMenuGroup } from '../../base-ui/menu/LitMainMenuGroup'; +import { LitMainMenuItem } from '../../base-ui/menu/LitMainMenuItem'; +import { SpRecordSetting } from './setting/SpRecordSetting'; +import { LitMainMenu, MenuGroup, MenuItem } from '../../base-ui/menu/LitMainMenu'; +import { SpProbesConfig } from './setting/SpProbesConfig'; +import { SpTraceCommand } from './setting/SpTraceCommand'; +import { FlagsConfig } from './SpFlags'; +import LitSwitch from '../../base-ui/switch/lit-switch'; import { LitSlider } from '../../base-ui/slider/LitSlider'; import { @@ -50,28 +50,28 @@ import { sysVMeminfoTypeFromJSON, TracePluginConfig, Type, -} from './setting/bean/ProfilerServiceTypes.js'; -import { PluginConvertUtils } from './setting/utils/PluginConvertUtils.js'; -import { SpAllocations } from './setting/SpAllocations.js'; -import { SpRecordPerf } from './setting/SpRecordPerf.js'; -import { HdcDeviceManager } from '../../hdc/HdcDeviceManager.js'; -import { LitButton } from '../../base-ui/button/LitButton.js'; -import { SpApplication } from '../SpApplication.js'; -import { LitSearch } from './trace/search/Search.js'; -import { LitProgressBar } from '../../base-ui/progress-bar/LitProgressBar.js'; -import { info, log } from '../../log/Log.js'; -import { CmdConstant } from '../../command/CmdConstant.js'; -import { Cmd } from '../../command/Cmd.js'; -import { SpFileSystem } from './setting/SpFileSystem.js'; -import { SpSdkConfig } from './setting/SpSdkConfig.js'; -import { SpVmTracker } from './setting/SpVmTracker.js'; -import { SpHisysEvent } from './setting/SpHisysEvent.js'; -import { SpRecordTemplate } from './setting/SpRecordTemplate.js'; -import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil.js'; -import { SpArkTs } from './setting/SpArkTs.js'; -import { SpWebHdcShell } from './setting/SpWebHdcShell.js'; -import { SpHilogRecord } from './setting/SpHilogRecord.js'; -import { LongTraceDBUtils } from '../database/LongTraceDBUtils.js'; +} from './setting/bean/ProfilerServiceTypes'; +import { PluginConvertUtils } from './setting/utils/PluginConvertUtils'; +import { SpAllocations } from './setting/SpAllocations'; +import { SpRecordPerf } from './setting/SpRecordPerf'; +import { HdcDeviceManager } from '../../hdc/HdcDeviceManager'; +import { LitButton } from '../../base-ui/button/LitButton'; +import { SpApplication } from '../SpApplication'; +import { LitSearch } from './trace/search/Search'; +import { LitProgressBar } from '../../base-ui/progress-bar/LitProgressBar'; +import { info, log } from '../../log/Log'; +import { CmdConstant } from '../../command/CmdConstant'; +import { Cmd } from '../../command/Cmd'; +import { SpFileSystem } from './setting/SpFileSystem'; +import { SpSdkConfig } from './setting/SpSdkConfig'; +import { SpVmTracker } from './setting/SpVmTracker'; +import { SpHisysEvent } from './setting/SpHisysEvent'; +import { SpRecordTemplate } from './setting/SpRecordTemplate'; +import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil'; +import { SpArkTs } from './setting/SpArkTs'; +import { SpWebHdcShell } from './setting/SpWebHdcShell'; +import { SpHilogRecord } from './setting/SpHilogRecord'; +import { LongTraceDBUtils } from '../database/LongTraceDBUtils'; @element('sp-record-trace') export class SpRecordTrace extends BaseElement { diff --git a/ide/src/trace/component/SpSystemTrace.ts b/ide/src/trace/component/SpSystemTrace.ts index 2de349931..99cbb8e29 100644 --- a/ide/src/trace/component/SpSystemTrace.ts +++ b/ide/src/trace/component/SpSystemTrace.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseElement, element } from '../../base-ui/BaseElement.js'; -import './trace/TimerShaftElement.js'; -import './trace/base/TraceRow.js'; +import { BaseElement, element } from '../../base-ui/BaseElement'; +import './trace/TimerShaftElement'; +import './trace/base/TraceRow'; import { queryBySelectAllocationOrReturn, queryBySelectExecute, @@ -23,20 +23,20 @@ import { querySceneSearchFunc, querySearchFunc, threadPool, -} from '../database/SqlLite.js'; -import { RangeSelectStruct, TraceRow } from './trace/base/TraceRow.js'; -import { TimerShaftElement } from './trace/TimerShaftElement.js'; -import './trace/base/TraceSheet.js'; -import { TraceSheet } from './trace/base/TraceSheet.js'; -import { RangeSelect } from './trace/base/RangeSelect.js'; -import { SelectionParam } from '../bean/BoxSelection.js'; -import { procedurePool } from '../database/Procedure.js'; -import { SpApplication } from '../SpApplication.js'; -import { Flag } from './trace/timer-shaft/Flag.js'; -import { SlicesTime, SportRuler } from './trace/timer-shaft/SportRuler.js'; -import { SpHiPerf } from './chart/SpHiPerf.js'; -import { SearchSdkBean, SearchThreadProcessBean } from '../bean/SearchFuncBean.js'; -import { error, info } from '../../log/Log.js'; +} from '../database/SqlLite'; +import { RangeSelectStruct, TraceRow } from './trace/base/TraceRow'; +import { TimerShaftElement } from './trace/TimerShaftElement'; +import './trace/base/TraceSheet'; +import { TraceSheet } from './trace/base/TraceSheet'; +import { RangeSelect } from './trace/base/RangeSelect'; +import { SelectionParam } from '../bean/BoxSelection'; +import { procedurePool } from '../database/Procedure'; +import { SpApplication } from '../SpApplication'; +import { Flag } from './trace/timer-shaft/Flag'; +import { SlicesTime, SportRuler } from './trace/timer-shaft/SportRuler'; +import { SpHiPerf } from './chart/SpHiPerf'; +import { SearchSdkBean, SearchThreadProcessBean } from '../bean/SearchFuncBean'; +import { error, info } from '../../log/Log'; import { drawFlagLineSegment, drawLines, @@ -49,64 +49,64 @@ import { ns2xByTimeShaft, PairPoint, Rect, -} from '../database/ui-worker/ProcedureWorkerCommon.js'; -import { SpChartManager } from './chart/SpChartManager.js'; -import { CpuStruct, WakeupBean } from '../database/ui-worker/ProcedureWorkerCPU.js'; -import { ProcessStruct } from '../database/ui-worker/ProcedureWorkerProcess.js'; -import { CpuFreqStruct } from '../database/ui-worker/ProcedureWorkerFreq.js'; -import { CpuFreqLimitsStruct } from '../database/ui-worker/ProcedureWorkerCpuFreqLimits.js'; -import { ThreadStruct } from '../database/ui-worker/ProcedureWorkerThread.js'; -import { func, FuncStruct } from '../database/ui-worker/ProcedureWorkerFunc.js'; -import { CpuStateStruct } from '../database/ui-worker/ProcedureWorkerCpuState.js'; -import { HiPerfCpuStruct } from '../database/ui-worker/ProcedureWorkerHiPerfCPU.js'; -import { HiPerfProcessStruct } from '../database/ui-worker/ProcedureWorkerHiPerfProcess.js'; -import { HiPerfThreadStruct } from '../database/ui-worker/ProcedureWorkerHiPerfThread.js'; -import { HiPerfEventStruct } from '../database/ui-worker/ProcedureWorkerHiPerfEvent.js'; -import { HiPerfReportStruct } from '../database/ui-worker/ProcedureWorkerHiPerfReport.js'; -import { FpsStruct } from '../database/ui-worker/ProcedureWorkerFPS.js'; -import { CpuAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerCpuAbility.js'; -import { DiskAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerDiskIoAbility.js'; -import { MemoryAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerMemoryAbility.js'; -import { NetworkAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerNetworkAbility.js'; -import { ClockStruct } from '../database/ui-worker/ProcedureWorkerClock.js'; -import { Utils } from './trace/base/Utils.js'; -import { IrqStruct } from '../database/ui-worker/ProcedureWorkerIrq.js'; -import { JanksStruct } from '../bean/JanksStruct.js'; -import { JankStruct } from '../database/ui-worker/ProcedureWorkerJank.js'; -import { TabPaneCurrent } from './trace/sheet/TabPaneCurrent.js'; -import { HeapStruct } from '../database/ui-worker/ProcedureWorkerHeap.js'; -import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil.js'; -import { HeapSnapshotStruct } from '../database/ui-worker/ProcedureWorkerHeapSnapshot.js'; -import { HeapDataInterface } from '../../js-heap/HeapDataInterface.js'; -import { LitTabs } from '../../base-ui/tabs/lit-tabs.js'; -import { TraceRowConfig } from './trace/base/TraceRowConfig.js'; -import { TabPaneCurrentSelection } from './trace/sheet/TabPaneCurrentSelection.js'; -import { SpChartList } from './trace/SpChartList.js'; -import './trace/SpChartList.js'; -import { AppStartupStruct } from '../database/ui-worker/ProcedureWorkerAppStartup.js'; -import { SoStruct } from '../database/ui-worker/ProcedureWorkerSoInit.js'; -import { TabPaneTaskFrames } from './trace/sheet/task/TabPaneTaskFrames.js'; -import { FlagsConfig } from './SpFlags.js'; -import { FrameDynamicStruct } from '../database/ui-worker/ProcedureWorkerFrameDynamic.js'; -import { FrameAnimationStruct } from '../database/ui-worker/ProcedureWorkerFrameAnimation.js'; -import { FrameSpacingStruct } from '../database/ui-worker/ProcedureWorkerFrameSpacing.js'; -import { JsCpuProfilerStruct } from '../database/ui-worker/ProcedureWorkerCpuProfiler.js'; -import { TabPaneSummary } from './trace/sheet/ark-ts/TabPaneSummary.js'; -import { JsCpuProfilerChartFrame } from '../bean/JsStruct.js'; -import { FileInfo } from '../../js-heap/model/UiStruct.js'; -import { SnapshotStruct } from '../database/ui-worker/ProcedureWorkerSnapshot.js'; -import { setSelectState, intersectData, isExistPidInArray } from './Utils.js'; -import { LogStruct } from '../database/ui-worker/ProcedureWorkerLog.js'; -import { TabPaneFrequencySample } from './trace/sheet/cpu/TabPaneFrequencySample.js'; -import { TabPaneCounterSample } from './trace/sheet/cpu/TabPaneCounterSample.js'; -import { LitSearch } from './trace/search/Search.js'; -import { TabPaneFlag } from './trace/timer-shaft/TabPaneFlag.js'; -import { LitTabpane } from '../../base-ui/tabs/lit-tabpane.js'; -import { HiPerfCallChartStruct } from '../database/ui-worker/ProcedureWorkerHiPerfCallChart.js'; -import { type HiSysEventStruct } from '../database/ui-worker/ProcedureWorkerHiSysEvent.js'; -import { InitAnalysis } from '../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { type SpKeyboard } from '../component/SpKeyboard.js'; -import { drawVSync, enableVSync, setVSyncDisable } from './chart/VSync.js'; +} from '../database/ui-worker/ProcedureWorkerCommon'; +import { SpChartManager } from './chart/SpChartManager'; +import { CpuStruct, WakeupBean } from '../database/ui-worker/ProcedureWorkerCPU'; +import { ProcessStruct } from '../database/ui-worker/ProcedureWorkerProcess'; +import { CpuFreqStruct } from '../database/ui-worker/ProcedureWorkerFreq'; +import { CpuFreqLimitsStruct } from '../database/ui-worker/ProcedureWorkerCpuFreqLimits'; +import { ThreadStruct } from '../database/ui-worker/ProcedureWorkerThread'; +import { func, FuncStruct } from '../database/ui-worker/ProcedureWorkerFunc'; +import { CpuStateStruct } from '../database/ui-worker/ProcedureWorkerCpuState'; +import { HiPerfCpuStruct } from '../database/ui-worker/ProcedureWorkerHiPerfCPU'; +import { HiPerfProcessStruct } from '../database/ui-worker/ProcedureWorkerHiPerfProcess'; +import { HiPerfThreadStruct } from '../database/ui-worker/ProcedureWorkerHiPerfThread'; +import { HiPerfEventStruct } from '../database/ui-worker/ProcedureWorkerHiPerfEvent'; +import { HiPerfReportStruct } from '../database/ui-worker/ProcedureWorkerHiPerfReport'; +import { FpsStruct } from '../database/ui-worker/ProcedureWorkerFPS'; +import { CpuAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerCpuAbility'; +import { DiskAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerDiskIoAbility'; +import { MemoryAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerMemoryAbility'; +import { NetworkAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerNetworkAbility'; +import { ClockStruct } from '../database/ui-worker/ProcedureWorkerClock'; +import { Utils } from './trace/base/Utils'; +import { IrqStruct } from '../database/ui-worker/ProcedureWorkerIrq'; +import { JanksStruct } from '../bean/JanksStruct'; +import { JankStruct } from '../database/ui-worker/ProcedureWorkerJank'; +import { TabPaneCurrent } from './trace/sheet/TabPaneCurrent'; +import { HeapStruct } from '../database/ui-worker/ProcedureWorkerHeap'; +import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil'; +import { HeapSnapshotStruct } from '../database/ui-worker/ProcedureWorkerHeapSnapshot'; +import { HeapDataInterface } from '../../js-heap/HeapDataInterface'; +import { LitTabs } from '../../base-ui/tabs/lit-tabs'; +import { TraceRowConfig } from './trace/base/TraceRowConfig'; +import { TabPaneCurrentSelection } from './trace/sheet/TabPaneCurrentSelection'; +import { SpChartList } from './trace/SpChartList'; +import './trace/SpChartList'; +import { AppStartupStruct } from '../database/ui-worker/ProcedureWorkerAppStartup'; +import { SoStruct } from '../database/ui-worker/ProcedureWorkerSoInit'; +import { TabPaneTaskFrames } from './trace/sheet/task/TabPaneTaskFrames'; +import { FlagsConfig } from './SpFlags'; +import { FrameDynamicStruct } from '../database/ui-worker/ProcedureWorkerFrameDynamic'; +import { FrameAnimationStruct } from '../database/ui-worker/ProcedureWorkerFrameAnimation'; +import { FrameSpacingStruct } from '../database/ui-worker/ProcedureWorkerFrameSpacing'; +import { JsCpuProfilerStruct } from '../database/ui-worker/ProcedureWorkerCpuProfiler'; +import { TabPaneSummary } from './trace/sheet/ark-ts/TabPaneSummary'; +import { JsCpuProfilerChartFrame } from '../bean/JsStruct'; +import { FileInfo } from '../../js-heap/model/UiStruct'; +import { SnapshotStruct } from '../database/ui-worker/ProcedureWorkerSnapshot'; +import { setSelectState, intersectData, isExistPidInArray } from './Utils'; +import { LogStruct } from '../database/ui-worker/ProcedureWorkerLog'; +import { TabPaneFrequencySample } from './trace/sheet/cpu/TabPaneFrequencySample'; +import { TabPaneCounterSample } from './trace/sheet/cpu/TabPaneCounterSample'; +import { LitSearch } from './trace/search/Search'; +import { TabPaneFlag } from './trace/timer-shaft/TabPaneFlag'; +import { LitTabpane } from '../../base-ui/tabs/lit-tabpane'; +import { HiPerfCallChartStruct } from '../database/ui-worker/ProcedureWorkerHiPerfCallChart'; +import { type HiSysEventStruct } from '../database/ui-worker/ProcedureWorkerHiSysEvent'; +import { InitAnalysis } from '../database/logic-worker/ProcedureLogicWorkerCommon'; +import { type SpKeyboard } from '../component/SpKeyboard'; +import { drawVSync, enableVSync, setVSyncDisable } from './chart/VSync'; function dpr() { return window.devicePixelRatio || 1; @@ -157,6 +157,7 @@ export class SpSystemTrace extends BaseElement { stateRowsId: Array = []; spacerEL: HTMLDivElement | undefined | null; visibleRows: Array> = []; + invisibleRows: Array> = []; collectRows: Array> = []; currentRow: TraceRow | undefined | null; keyboardEnable = true; @@ -302,9 +303,9 @@ export class SpSystemTrace extends BaseElement { let rightStar: HTMLElement | null | undefined = this.traceSheetEL?.shadowRoot ?.querySelector('#current-selection > tabpane-current-selection') ?.shadowRoot?.querySelector('#right-star'); - this.rowsEL = this.shadowRoot?.querySelector('.rows'); this.tipEL = this.shadowRoot?.querySelector('.tip'); this.rowsPaneEL = this.shadowRoot?.querySelector('.rows-pane'); + this.rowsEL = this.rowsPaneEL; this.spacerEL = this.shadowRoot?.querySelector('.spacer'); this.timerShaftEL = this.shadowRoot?.querySelector('.timer-shaft'); this.favoriteChartListEL = this.shadowRoot?.querySelector('#favorite-chart-list'); @@ -1394,18 +1395,24 @@ export class SpSystemTrace extends BaseElement { let tr = it.target as TraceRow; if (!it.isIntersecting) { tr.sleeping = true; + this.invisibleRows.push(tr); this.visibleRows = this.visibleRows.filter((it) => !it.sleeping); } else { - if ( - !this.visibleRows.find( - (vr) => vr.rowId === tr.rowId && vr.rowType === tr.rowType && vr.rowParentId === tr.rowParentId - ) - ) { - this.visibleRows.push(tr); - } tr.sleeping = false; + this.visibleRows.push(tr); + this.invisibleRows = this.invisibleRows.filter((it) => it.sleeping); + } + this.visibleRows + .filter((vr) => vr.expansion) + .forEach((vr) => { + vr.sticky = this.visibleRows.some((vro) => vr.childrenList.filter((it) => !it.collect).indexOf(vro) >= 0); + }); + this.visibleRows + .filter((vr) => !vr.folder && vr.parentRowEl && vr.parentRowEl.expansion) + .forEach((vr) => (vr.parentRowEl!.sticky = true)); + if (this.handler) { + clearTimeout(this.handler); } - if (this.handler) clearTimeout(this.handler); this.handler = setTimeout(() => this.refreshCanvas(false), 100); }); }); @@ -1465,6 +1472,7 @@ export class SpSystemTrace extends BaseElement { this.currentCollectGroup = group; }); } + // 清除上一次点击调用栈产生的三角旗子 private clearTriangle(flagList: Array) { this.timerShaftEL!.sportRuler!.times = []; @@ -4384,7 +4392,6 @@ export class SpSystemTrace extends BaseElement { row.clearMemory(); this.rowsEL!.removeChild(row); }); - this.rowsEL.innerHTML = ''; } this.traceSheetEL?.clearMemory(); this.spacerEL!.style.height = '0px'; diff --git a/ide/src/trace/component/SpWelcomePage.ts b/ide/src/trace/component/SpWelcomePage.ts index 59d9e29a3..8f3fe59e3 100644 --- a/ide/src/trace/component/SpWelcomePage.ts +++ b/ide/src/trace/component/SpWelcomePage.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../../base-ui/BaseElement.js'; +import { BaseElement, element } from '../../base-ui/BaseElement'; @element('sp-welcome') export class SpWelcomePage extends BaseElement { diff --git a/ide/src/trace/component/StackBar.ts b/ide/src/trace/component/StackBar.ts index ed7f1c974..162599b34 100644 --- a/ide/src/trace/component/StackBar.ts +++ b/ide/src/trace/component/StackBar.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseElement, element } from '../../base-ui/BaseElement.js'; -import { SelectionData } from '../bean/BoxSelection.js'; -import { Utils } from './trace/base/Utils.js'; +import { BaseElement, element } from '../../base-ui/BaseElement'; +import { SelectionData } from '../bean/BoxSelection'; +import { Utils } from './trace/base/Utils'; @element('stack-bar') export class StackBar extends BaseElement { diff --git a/ide/src/trace/component/Utils.ts b/ide/src/trace/component/Utils.ts index 84ac77a5d..a3b666cfb 100644 --- a/ide/src/trace/component/Utils.ts +++ b/ide/src/trace/component/Utils.ts @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { type JsCpuProfilerChartFrame } from '../bean/JsStruct.js'; -import { type SnapshotStruct } from '../database/ui-worker/ProcedureWorkerSnapshot.js'; -import { type RangeSelectStruct, TraceRow } from './trace/base/TraceRow.js'; +import { type JsCpuProfilerChartFrame } from '../bean/JsStruct'; +import { type SnapshotStruct } from '../database/ui-worker/ProcedureWorkerSnapshot'; +import { type RangeSelectStruct, TraceRow } from './trace/base/TraceRow'; export function setSelectState( data: JsCpuProfilerChartFrame, diff --git a/ide/src/trace/component/chart/FrameChart.ts b/ide/src/trace/component/chart/FrameChart.ts index 780f50953..f9b652fd8 100644 --- a/ide/src/trace/component/chart/FrameChart.ts +++ b/ide/src/trace/component/chart/FrameChart.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { Rect } from '../trace/timer-shaft/Rect.js'; -import { ChartMode, ChartStruct, draw, setFuncFrame } from '../../bean/FrameChartStruct.js'; -import { SpApplication } from '../../SpApplication.js'; -import { Utils } from '../trace/base/Utils.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { Rect } from '../trace/timer-shaft/Rect'; +import { ChartMode, ChartStruct, draw, setFuncFrame } from '../../bean/FrameChartStruct'; +import { SpApplication } from '../../SpApplication'; +import { Utils } from '../trace/base/Utils'; const scaleHeight = 30; // 刻度尺高度 const depthHeight = 20; // 调用栈高度 diff --git a/ide/src/trace/component/chart/PerfDataQuery.ts b/ide/src/trace/component/chart/PerfDataQuery.ts index 9de3f4ff3..b01c337fb 100644 --- a/ide/src/trace/component/chart/PerfDataQuery.ts +++ b/ide/src/trace/component/chart/PerfDataQuery.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { queryPerfFiles } from '../../database/SqlLite.js'; -import { PerfCall, PerfFile } from '../../bean/PerfProfile.js'; -import { info } from '../../../log/Log.js'; -import { SpHiPerf } from './SpHiPerf.js'; -import { procedurePool } from '../../database/Procedure.js'; +import { queryPerfFiles } from '../../database/SqlLite'; +import { PerfCall, PerfFile } from '../../bean/PerfProfile'; +import { info } from '../../../log/Log'; +import { SpHiPerf } from './SpHiPerf'; +import { procedurePool } from '../../database/Procedure'; import {PerfCallChain} from "../../database/logic-worker/ProcedureLogicWorkerPerf"; export class PerfDataQuery { diff --git a/ide/src/trace/component/chart/SpAbilityMonitorChart.ts b/ide/src/trace/component/chart/SpAbilityMonitorChart.ts index 0cdc81271..904df00c7 100644 --- a/ide/src/trace/component/chart/SpAbilityMonitorChart.ts +++ b/ide/src/trace/component/chart/SpAbilityMonitorChart.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; +import { SpSystemTrace } from '../SpSystemTrace'; import { queryAbilityExits, queryBytesInAbilityData, @@ -37,27 +37,27 @@ import { queryPurgeableSysData, queryReadAbilityData, queryWrittenAbilityData, -} from '../../database/SqlLite.js'; -import { info } from '../../../log/Log.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { Utils } from '../trace/base/Utils.js'; -import { type EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { type ProcessStruct } from '../../database/ui-worker/ProcedureWorkerProcess.js'; -import { CpuAbilityMonitorStruct, CpuAbilityRender } from '../../database/ui-worker/ProcedureWorkerCpuAbility.js'; +} from '../../database/SqlLite'; +import { info } from '../../../log/Log'; +import { TraceRow } from '../trace/base/TraceRow'; +import { Utils } from '../trace/base/Utils'; +import { type EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { type ProcessStruct } from '../../database/ui-worker/ProcedureWorkerProcess'; +import { CpuAbilityMonitorStruct, CpuAbilityRender } from '../../database/ui-worker/ProcedureWorkerCpuAbility'; import { MemoryAbilityMonitorStruct, MemoryAbilityRender, -} from '../../database/ui-worker/ProcedureWorkerMemoryAbility.js'; +} from '../../database/ui-worker/ProcedureWorkerMemoryAbility'; import { DiskAbilityMonitorStruct, DiskIoAbilityRender, -} from '../../database/ui-worker/ProcedureWorkerDiskIoAbility.js'; +} from '../../database/ui-worker/ProcedureWorkerDiskIoAbility'; import { NetworkAbilityMonitorStruct, NetworkAbilityRender, -} from '../../database/ui-worker/ProcedureWorkerNetworkAbility.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { type SnapshotRender, SnapshotStruct } from '../../database/ui-worker/ProcedureWorkerSnapshot.js'; +} from '../../database/ui-worker/ProcedureWorkerNetworkAbility'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { type SnapshotRender, SnapshotStruct } from '../../database/ui-worker/ProcedureWorkerSnapshot'; export class SpAbilityMonitorChart { private trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/SpArkTsChart.ts b/ide/src/trace/component/chart/SpArkTsChart.ts index e3c1c500d..678660d01 100644 --- a/ide/src/trace/component/chart/SpArkTsChart.ts +++ b/ide/src/trace/component/chart/SpArkTsChart.ts @@ -12,22 +12,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { info } from '../../../log/Log.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { type EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { type HeapTimelineRender, HeapTimelineStruct } from '../../database/ui-worker/ProcedureWorkerHeapTimeline.js'; -import { HeapDataInterface, type ParseListener } from '../../../js-heap/HeapDataInterface.js'; -import { LoadDatabase } from '../../../js-heap/LoadDatabase.js'; -import { type FileInfo } from '../../../js-heap/model/UiStruct.js'; -import { type HeapSnapshotRender, HeapSnapshotStruct } from '../../database/ui-worker/ProcedureWorkerHeapSnapshot.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { Utils } from '../trace/base/Utils.js'; -import { type JsCpuProfilerChartFrame } from '../../bean/JsStruct.js'; -import { type JsCpuProfilerRender, JsCpuProfilerStruct } from '../../database/ui-worker/ProcedureWorkerCpuProfiler.js'; -import { ns2s } from '../../database/ui-worker/ProcedureWorkerCommon.js'; -import { queryJsCpuProfilerConfig, queryJsCpuProfilerData, queryJsMemoryData } from '../../database/SqlLite.js'; +import { SpSystemTrace } from '../SpSystemTrace'; +import { TraceRow } from '../trace/base/TraceRow'; +import { info } from '../../../log/Log'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { type EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { type HeapTimelineRender, HeapTimelineStruct } from '../../database/ui-worker/ProcedureWorkerHeapTimeline'; +import { HeapDataInterface, type ParseListener } from '../../../js-heap/HeapDataInterface'; +import { LoadDatabase } from '../../../js-heap/LoadDatabase'; +import { type FileInfo } from '../../../js-heap/model/UiStruct'; +import { type HeapSnapshotRender, HeapSnapshotStruct } from '../../database/ui-worker/ProcedureWorkerHeapSnapshot'; +import { procedurePool } from '../../database/Procedure'; +import { Utils } from '../trace/base/Utils'; +import { type JsCpuProfilerChartFrame } from '../../bean/JsStruct'; +import { type JsCpuProfilerRender, JsCpuProfilerStruct } from '../../database/ui-worker/ProcedureWorkerCpuProfiler'; +import { ns2s } from '../../database/ui-worker/ProcedureWorkerCommon'; +import { queryJsCpuProfilerConfig, queryJsCpuProfilerData, queryJsMemoryData } from '../../database/SqlLite'; const TYPE_SNAPSHOT = 0; const TYPE_TIMELINE = 1; export class SpArkTsChart implements ParseListener { diff --git a/ide/src/trace/component/chart/SpChartManager.ts b/ide/src/trace/component/chart/SpChartManager.ts index a8fa7c6f7..fc9b1fc2a 100644 --- a/ide/src/trace/component/chart/SpChartManager.ts +++ b/ide/src/trace/component/chart/SpChartManager.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { SpHiPerf } from './SpHiPerf.js'; -import { SpCpuChart } from './SpCpuChart.js'; -import { SpFreqChart } from './SpFreqChart.js'; -import { SpFpsChart } from './SpFpsChart.js'; +import { SpSystemTrace } from '../SpSystemTrace'; +import { SpHiPerf } from './SpHiPerf'; +import { SpCpuChart } from './SpCpuChart'; +import { SpFreqChart } from './SpFreqChart'; +import { SpFpsChart } from './SpFpsChart'; import { getCpuUtilizationRate, queryAppStartupProcessIds, @@ -26,30 +26,30 @@ import { queryTaskPoolCallStack, queryThreadAndProcessName, queryTotalTime, -} from '../../database/SqlLite.js'; -import { info } from '../../../log/Log.js'; -import { SpNativeMemoryChart } from './SpNativeMemoryChart.js'; -import { SpAbilityMonitorChart } from './SpAbilityMonitorChart.js'; -import { SpProcessChart } from './SpProcessChart.js'; -import { perfDataQuery } from './PerfDataQuery.js'; -import { SpVirtualMemChart } from './SpVirtualMemChart.js'; -import { SpFileSystemChart } from './SpFileSystemChart.js'; -import { SpSdkChart } from './SpSdkChart.js'; -import { SpHiSysEnergyChart } from './SpHiSysEnergyChart.js'; -import { VmTrackerChart } from './SpVmTrackerChart.js'; -import { SpClockChart } from './SpClockChart.js'; -import { SpIrqChart } from './SpIrqChart.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { SpFrameTimeChart } from './SpFrameTimeChart.js'; -import { Utils } from '../trace/base/Utils.js'; -import { SpArkTsChart } from './SpArkTsChart.js'; -import { MemoryConfig } from '../../bean/MemoryConfig.js'; -import { FlagsConfig } from '../SpFlags.js'; -import { SpLogChart } from './SpLogChart.js'; -import { SpHiSysEventChart } from './SpHiSysEventChart.js'; -import {setVSyncData} from './VSync.js'; +} from '../../database/SqlLite'; +import { info } from '../../../log/Log'; +import { SpNativeMemoryChart } from './SpNativeMemoryChart'; +import { SpAbilityMonitorChart } from './SpAbilityMonitorChart'; +import { SpProcessChart } from './SpProcessChart'; +import { perfDataQuery } from './PerfDataQuery'; +import { SpVirtualMemChart } from './SpVirtualMemChart'; +import { SpFileSystemChart } from './SpFileSystemChart'; +import { SpSdkChart } from './SpSdkChart'; +import { SpHiSysEnergyChart } from './SpHiSysEnergyChart'; +import { VmTrackerChart } from './SpVmTrackerChart'; +import { SpClockChart } from './SpClockChart'; +import { SpIrqChart } from './SpIrqChart'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { TraceRow } from '../trace/base/TraceRow'; +import { SpFrameTimeChart } from './SpFrameTimeChart'; +import { Utils } from '../trace/base/Utils'; +import { SpArkTsChart } from './SpArkTsChart'; +import { MemoryConfig } from '../../bean/MemoryConfig'; +import { FlagsConfig } from '../SpFlags'; +import { SpLogChart } from './SpLogChart'; +import { SpHiSysEventChart } from './SpHiSysEventChart'; +import {setVSyncData} from './VSync'; export class SpChartManager { static APP_STARTUP_PID_ARR: Array = []; diff --git a/ide/src/trace/component/chart/SpClockChart.ts b/ide/src/trace/component/chart/SpClockChart.ts index 2da72725a..74c4c2d4a 100644 --- a/ide/src/trace/component/chart/SpClockChart.ts +++ b/ide/src/trace/component/chart/SpClockChart.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { queryClockData, queryClockFrequency, queryClockState, queryScreenState } from '../../database/SqlLite.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { info } from '../../../log/Log.js'; -import { ClockRender, ClockStruct } from '../../database/ui-worker/ProcedureWorkerClock.js'; -import { ColorUtils } from '../trace/base/ColorUtils.js'; -import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { Utils } from '../trace/base/Utils.js'; +import { SpSystemTrace } from '../SpSystemTrace'; +import { queryClockData, queryClockFrequency, queryClockState, queryScreenState } from '../../database/SqlLite'; +import { TraceRow } from '../trace/base/TraceRow'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { info } from '../../../log/Log'; +import { ClockRender, ClockStruct } from '../../database/ui-worker/ProcedureWorkerClock'; +import { ColorUtils } from '../trace/base/ColorUtils'; +import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { Utils } from '../trace/base/Utils'; export class SpClockChart { private trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/SpCpuChart.ts b/ide/src/trace/component/chart/SpCpuChart.ts index 995c3849d..73d825ae0 100644 --- a/ide/src/trace/component/chart/SpCpuChart.ts +++ b/ide/src/trace/component/chart/SpCpuChart.ts @@ -13,20 +13,20 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; +import { SpSystemTrace } from '../SpSystemTrace'; import { queryCpuCount, queryCpuData, queryCpuDataCount, queryCpuMax, queryCpuSchedSlice, -} from '../../database/SqlLite.js'; -import { info } from '../../../log/Log.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { CpuRender, CpuStruct } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { Utils } from '../trace/base/Utils.js'; +} from '../../database/SqlLite'; +import { info } from '../../../log/Log'; +import { TraceRow } from '../trace/base/TraceRow'; +import { procedurePool } from '../../database/Procedure'; +import { CpuRender, CpuStruct } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { Utils } from '../trace/base/Utils'; export class SpCpuChart { private trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/SpFileSystemChart.ts b/ide/src/trace/component/chart/SpFileSystemChart.ts index 458cf57c5..02e1badb2 100644 --- a/ide/src/trace/component/chart/SpFileSystemChart.ts +++ b/ide/src/trace/component/chart/SpFileSystemChart.ts @@ -13,21 +13,21 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { procedurePool } from '../../database/Procedure.js'; +import { SpSystemTrace } from '../SpSystemTrace'; +import { TraceRow } from '../trace/base/TraceRow'; +import { procedurePool } from '../../database/Procedure'; import { getDiskIOLatencyChartDataByProcess, getDiskIOProcess, getFileSysChartDataByType, getFileSysVirtualMemoryChartData, hasFileSysData, -} from '../../database/SqlLite.js'; -import { FileSysChartStruct, FileSystemRender } from '../../database/ui-worker/ProcedureWorkerFileSystem.js'; -import { ColorUtils } from '../trace/base/ColorUtils.js'; -import { Utils } from '../trace/base/Utils.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; +} from '../../database/SqlLite'; +import { FileSysChartStruct, FileSystemRender } from '../../database/ui-worker/ProcedureWorkerFileSystem'; +import { ColorUtils } from '../trace/base/ColorUtils'; +import { Utils } from '../trace/base/Utils'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; export class SpFileSystemChart { private trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/SpFpsChart.ts b/ide/src/trace/component/chart/SpFpsChart.ts index 3a4036629..468c4421f 100644 --- a/ide/src/trace/component/chart/SpFpsChart.ts +++ b/ide/src/trace/component/chart/SpFpsChart.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { getFps } from '../../database/SqlLite.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { info } from '../../../log/Log.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { FpsRender, FpsStruct } from '../../database/ui-worker/ProcedureWorkerFPS.js'; +import { SpSystemTrace } from '../SpSystemTrace'; +import { getFps } from '../../database/SqlLite'; +import { TraceRow } from '../trace/base/TraceRow'; +import { info } from '../../../log/Log'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { FpsRender, FpsStruct } from '../../database/ui-worker/ProcedureWorkerFPS'; export class SpFpsChart { private trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/SpFrameTimeChart.ts b/ide/src/trace/component/chart/SpFrameTimeChart.ts index 73c0938a2..d6fefd4bd 100644 --- a/ide/src/trace/component/chart/SpFrameTimeChart.ts +++ b/ide/src/trace/component/chart/SpFrameTimeChart.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { TraceRow } from '../trace/base/TraceRow.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { JankRender, JankStruct } from '../../database/ui-worker/ProcedureWorkerJank.js'; -import { SpSystemTrace } from '../SpSystemTrace.js'; +import { TraceRow } from '../trace/base/TraceRow'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { JankRender, JankStruct } from '../../database/ui-worker/ProcedureWorkerJank'; +import { SpSystemTrace } from '../SpSystemTrace'; import { queryActualFrameDate, queryExpectedFrameDate, @@ -26,17 +26,17 @@ import { queryFrameSpacing, queryFrameTimeData, queryPhysicalData, -} from '../../database/SqlLite.js'; -import { JanksStruct } from '../../bean/JanksStruct.js'; -import { ns2xByTimeShaft, type PairPoint } from '../../database/ui-worker/ProcedureWorkerCommon.js'; -import { FrameDynamicRender, FrameDynamicStruct } from '../../database/ui-worker/ProcedureWorkerFrameDynamic.js'; -import { FrameAnimationRender, FrameAnimationStruct } from '../../database/ui-worker/ProcedureWorkerFrameAnimation.js'; -import { type BaseStruct } from '../../bean/BaseStruct.js'; -import { FrameSpacingRender, FrameSpacingStruct } from '../../database/ui-worker/ProcedureWorkerFrameSpacing.js'; -import { FlagsConfig, type Params } from '../SpFlags.js'; -import { type AnimationRanges, type DeviceStruct } from '../../bean/FrameComponentBean.js'; -import { type EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { TreeItemData } from '../../../base-ui/tree/LitTree.js'; +} from '../../database/SqlLite'; +import { JanksStruct } from '../../bean/JanksStruct'; +import { ns2xByTimeShaft, type PairPoint } from '../../database/ui-worker/ProcedureWorkerCommon'; +import { FrameDynamicRender, FrameDynamicStruct } from '../../database/ui-worker/ProcedureWorkerFrameDynamic'; +import { FrameAnimationRender, FrameAnimationStruct } from '../../database/ui-worker/ProcedureWorkerFrameAnimation'; +import { type BaseStruct } from '../../bean/BaseStruct'; +import { FrameSpacingRender, FrameSpacingStruct } from '../../database/ui-worker/ProcedureWorkerFrameSpacing'; +import { FlagsConfig, type Params } from '../SpFlags'; +import { type AnimationRanges, type DeviceStruct } from '../../bean/FrameComponentBean'; +import { type EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { TreeItemData } from '../../../base-ui/tree/LitTree'; export class SpFrameTimeChart { private trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/SpFreqChart.ts b/ide/src/trace/component/chart/SpFreqChart.ts index a4abd31f8..d70049d94 100644 --- a/ide/src/trace/component/chart/SpFreqChart.ts +++ b/ide/src/trace/component/chart/SpFreqChart.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; +import { SpSystemTrace } from '../SpSystemTrace'; import { getCpuLimitFreq, getCpuLimitFreqId, @@ -24,16 +24,16 @@ import { queryCpuMaxFreq, queryCpuState, queryCpuStateFilter, -} from '../../database/SqlLite.js'; -import { info } from '../../../log/Log.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { ColorUtils } from '../trace/base/ColorUtils.js'; -import { CpuFreqLimitRender, CpuFreqLimitsStruct } from '../../database/ui-worker/ProcedureWorkerCpuFreqLimits.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { CpuFreqStruct, FreqRender } from '../../database/ui-worker/ProcedureWorkerFreq.js'; -import { CpuStateRender, CpuStateStruct } from '../../database/ui-worker/ProcedureWorkerCpuState.js'; -import { FolderSupplier, FolderThreadHandler } from './SpChartManager.js'; -import { Utils } from '../trace/base/Utils.js'; +} from '../../database/SqlLite'; +import { info } from '../../../log/Log'; +import { TraceRow } from '../trace/base/TraceRow'; +import { ColorUtils } from '../trace/base/ColorUtils'; +import { CpuFreqLimitRender, CpuFreqLimitsStruct } from '../../database/ui-worker/ProcedureWorkerCpuFreqLimits'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { CpuFreqStruct, FreqRender } from '../../database/ui-worker/ProcedureWorkerFreq'; +import { CpuStateRender, CpuStateStruct } from '../../database/ui-worker/ProcedureWorkerCpuState'; +import { FolderSupplier, FolderThreadHandler } from './SpChartManager'; +import { Utils } from '../trace/base/Utils'; export class SpFreqChart { private trace: SpSystemTrace; private folderRow: TraceRow | undefined; diff --git a/ide/src/trace/component/chart/SpHiPerf.ts b/ide/src/trace/component/chart/SpHiPerf.ts index 3e1d8c91d..439975f86 100644 --- a/ide/src/trace/component/chart/SpHiPerf.ts +++ b/ide/src/trace/component/chart/SpHiPerf.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; +import { SpSystemTrace } from '../SpSystemTrace'; +import { TraceRow } from '../trace/base/TraceRow'; import { queryHiPerfCpuData, queryHiPerfCpuMergeData, @@ -24,22 +24,22 @@ import { queryPerfEventType, queryPerfCmdline, queryPerfThread, -} from '../../database/SqlLite.js'; -import { Utils } from '../trace/base/Utils.js'; -import { PerfThread } from '../../bean/PerfProfile.js'; -import { HiperfCpuRender, HiPerfCpuStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfCPU.js'; -import { HiPerfCallChartRender, HiPerfCallChartStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfCallChart.js'; -import { HiperfThreadRender, HiPerfThreadStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfThread.js'; -import { HiperfProcessRender, HiPerfProcessStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfProcess.js'; -import { info } from '../../../log/Log.js'; -import { HiPerfEventStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfEvent.js'; -import { perfDataQuery } from './PerfDataQuery.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { type HiPerfReportStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfReport.js'; -import { SpChartManager } from './SpChartManager.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { HiPerfChartFrame } from '../../bean/PerfStruct.js'; +} from '../../database/SqlLite'; +import { Utils } from '../trace/base/Utils'; +import { PerfThread } from '../../bean/PerfProfile'; +import { HiperfCpuRender, HiPerfCpuStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfCPU'; +import { HiPerfCallChartRender, HiPerfCallChartStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfCallChart'; +import { HiperfThreadRender, HiPerfThreadStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfThread'; +import { HiperfProcessRender, HiPerfProcessStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfProcess'; +import { info } from '../../../log/Log'; +import { HiPerfEventStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfEvent'; +import { perfDataQuery } from './PerfDataQuery'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { type HiPerfReportStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfReport'; +import { SpChartManager } from './SpChartManager'; +import { procedurePool } from '../../database/Procedure'; +import { HiPerfChartFrame } from '../../bean/PerfStruct'; export interface ResultData { existA: boolean | null | undefined; diff --git a/ide/src/trace/component/chart/SpHiSysEnergyChart.ts b/ide/src/trace/component/chart/SpHiSysEnergyChart.ts index 6a157667b..cc2f69c63 100644 --- a/ide/src/trace/component/chart/SpHiSysEnergyChart.ts +++ b/ide/src/trace/component/chart/SpHiSysEnergyChart.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; +import { SpSystemTrace } from '../SpSystemTrace'; import { queryAnomalyData, queryConfigEnergyAppName, @@ -26,17 +26,17 @@ import { querySystemLocationData, querySystemLockData, querySystemSchedulerData, -} from '../../database/SqlLite.js'; -import { info } from '../../../log/Log.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { BaseStruct } from '../../bean/BaseStruct.js'; -import { EnergyAnomalyRender, EnergyAnomalyStruct } from '../../database/ui-worker/ProcedureWorkerEnergyAnomaly.js'; -import { EnergySystemStruct, EnergySystemRender } from '../../database/ui-worker/ProcedureWorkerEnergySystem.js'; -import { EnergyPowerStruct, EnergyPowerRender } from '../../database/ui-worker/ProcedureWorkerEnergyPower.js'; -import { EnergyStateStruct, EnergyStateRender } from '../../database/ui-worker/ProcedureWorkerEnergyState.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { TreeItemData } from '../../../base-ui/tree/LitTree.js'; +} from '../../database/SqlLite'; +import { info } from '../../../log/Log'; +import { TraceRow } from '../trace/base/TraceRow'; +import { BaseStruct } from '../../bean/BaseStruct'; +import { EnergyAnomalyRender, EnergyAnomalyStruct } from '../../database/ui-worker/ProcedureWorkerEnergyAnomaly'; +import { EnergySystemStruct, EnergySystemRender } from '../../database/ui-worker/ProcedureWorkerEnergySystem'; +import { EnergyPowerStruct, EnergyPowerRender } from '../../database/ui-worker/ProcedureWorkerEnergyPower'; +import { EnergyStateStruct, EnergyStateRender } from '../../database/ui-worker/ProcedureWorkerEnergyState'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { TreeItemData } from '../../../base-ui/tree/LitTree'; export class SpHiSysEnergyChart { static app_name: string | null; diff --git a/ide/src/trace/component/chart/SpHiSysEventChart.ts b/ide/src/trace/component/chart/SpHiSysEventChart.ts index bfb2dccbd..25caff862 100644 --- a/ide/src/trace/component/chart/SpHiSysEventChart.ts +++ b/ide/src/trace/component/chart/SpHiSysEventChart.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { HiSysEventRender, HiSysEventStruct } from '../../database/ui-worker/ProcedureWorkerHiSysEvent.js'; -import { queryHiSysEventData } from '../../database/SqlLite.js'; +import { SpSystemTrace } from '../SpSystemTrace'; +import { TraceRow } from '../trace/base/TraceRow'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { HiSysEventRender, HiSysEventStruct } from '../../database/ui-worker/ProcedureWorkerHiSysEvent'; +import { queryHiSysEventData } from '../../database/SqlLite'; export class SpHiSysEventChart { private trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/SpIrqChart.ts b/ide/src/trace/component/chart/SpIrqChart.ts index b28001936..87ec79aa8 100644 --- a/ide/src/trace/component/chart/SpIrqChart.ts +++ b/ide/src/trace/component/chart/SpIrqChart.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { queryIrqData, queryIrqList } from '../../database/SqlLite.js'; -import { info } from '../../../log/Log.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { IrqRender, IrqStruct } from '../../database/ui-worker/ProcedureWorkerIrq.js'; +import { SpSystemTrace } from '../SpSystemTrace'; +import { TraceRow } from '../trace/base/TraceRow'; +import { queryIrqData, queryIrqList } from '../../database/SqlLite'; +import { info } from '../../../log/Log'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { IrqRender, IrqStruct } from '../../database/ui-worker/ProcedureWorkerIrq'; export class SpIrqChart { private trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/SpLogChart.ts b/ide/src/trace/component/chart/SpLogChart.ts index b59ae3986..371ea77ea 100644 --- a/ide/src/trace/component/chart/SpLogChart.ts +++ b/ide/src/trace/component/chart/SpLogChart.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { queryLogData } from '../../database/SqlLite.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { LogRender, LogStruct } from '../../database/ui-worker/ProcedureWorkerLog.js'; +import { SpSystemTrace } from '../SpSystemTrace'; +import { TraceRow } from '../trace/base/TraceRow'; +import { queryLogData } from '../../database/SqlLite'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { LogRender, LogStruct } from '../../database/ui-worker/ProcedureWorkerLog'; const ONE_DAY_NS = 86400000000000; diff --git a/ide/src/trace/component/chart/SpNativeMemoryChart.ts b/ide/src/trace/component/chart/SpNativeMemoryChart.ts index e28619b23..25088ab78 100644 --- a/ide/src/trace/component/chart/SpNativeMemoryChart.ts +++ b/ide/src/trace/component/chart/SpNativeMemoryChart.ts @@ -13,23 +13,23 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; +import { SpSystemTrace } from '../SpSystemTrace'; import { queryBootTime, queryHeapGroupByEvent, queryNativeHookProcess, queryNativeHookStatisticsCount, queryNativeMemoryRealTime, -} from '../../database/SqlLite.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { info } from '../../../log/Log.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { type NativeEventHeap } from '../../bean/NativeHook.js'; -import { HeapRender, HeapStruct } from '../../database/ui-worker/ProcedureWorkerHeap.js'; -import { Utils } from '../trace/base/Utils.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { type BaseStruct } from '../../bean/BaseStruct.js'; +} from '../../database/SqlLite'; +import { TraceRow } from '../trace/base/TraceRow'; +import { info } from '../../../log/Log'; +import { procedurePool } from '../../database/Procedure'; +import { type NativeEventHeap } from '../../bean/NativeHook'; +import { HeapRender, HeapStruct } from '../../database/ui-worker/ProcedureWorkerHeap'; +import { Utils } from '../trace/base/Utils'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { type BaseStruct } from '../../bean/BaseStruct'; export class SpNativeMemoryChart { static EVENT_HEAP: Array = []; diff --git a/ide/src/trace/component/chart/SpProcessChart.ts b/ide/src/trace/component/chart/SpProcessChart.ts index d4e2d0684..830e46b37 100644 --- a/ide/src/trace/component/chart/SpProcessChart.ts +++ b/ide/src/trace/component/chart/SpProcessChart.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; +import { SpSystemTrace } from '../SpSystemTrace'; import { getFunDataByTid, getMaxDepthByTid, @@ -36,22 +36,22 @@ import { queryProcessThreadsByTable, queryStartupPidArray, queryThreadData, -} from '../../database/SqlLite.js'; -import { Utils } from '../trace/base/Utils.js'; -import { info } from '../../../log/Log.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { ProcessRender, ProcessStruct } from '../../database/ui-worker/ProcedureWorkerProcess.js'; -import { ThreadRender, ThreadStruct } from '../../database/ui-worker/ProcedureWorkerThread.js'; -import { FuncRender, FuncStruct } from '../../database/ui-worker/ProcedureWorkerFunc.js'; -import { MemRender, ProcessMemStruct } from '../../database/ui-worker/ProcedureWorkerMem.js'; -import { FolderSupplier, FolderThreadHandler, SpChartManager } from './SpChartManager.js'; -import { JankRender, JankStruct } from '../../database/ui-worker/ProcedureWorkerJank.js'; -import { ns2xByTimeShaft } from '../../database/ui-worker/ProcedureWorkerCommon.js'; -import { AppStartupRender, AppStartupStruct } from '../../database/ui-worker/ProcedureWorkerAppStartup.js'; -import { SoRender, SoStruct } from '../../database/ui-worker/ProcedureWorkerSoInit.js'; -import { FlagsConfig } from '../SpFlags.js'; -import { JanksStruct } from '../../bean/JanksStruct.js'; +} from '../../database/SqlLite'; +import { Utils } from '../trace/base/Utils'; +import { info } from '../../../log/Log'; +import { TraceRow } from '../trace/base/TraceRow'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { ProcessRender, ProcessStruct } from '../../database/ui-worker/ProcedureWorkerProcess'; +import { ThreadRender, ThreadStruct } from '../../database/ui-worker/ProcedureWorkerThread'; +import { FuncRender, FuncStruct } from '../../database/ui-worker/ProcedureWorkerFunc'; +import { MemRender, ProcessMemStruct } from '../../database/ui-worker/ProcedureWorkerMem'; +import { FolderSupplier, FolderThreadHandler, SpChartManager } from './SpChartManager'; +import { JankRender, JankStruct } from '../../database/ui-worker/ProcedureWorkerJank'; +import { ns2xByTimeShaft } from '../../database/ui-worker/ProcedureWorkerCommon'; +import { AppStartupRender, AppStartupStruct } from '../../database/ui-worker/ProcedureWorkerAppStartup'; +import { SoRender, SoStruct } from '../../database/ui-worker/ProcedureWorkerSoInit'; +import { FlagsConfig } from '../SpFlags'; +import { JanksStruct } from '../../bean/JanksStruct'; export class SpProcessChart { private readonly trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/SpSdkChart.ts b/ide/src/trace/component/chart/SpSdkChart.ts index 7a04c1b5b..defce4418 100644 --- a/ide/src/trace/component/chart/SpSdkChart.ts +++ b/ide/src/trace/component/chart/SpSdkChart.ts @@ -13,22 +13,22 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; +import { SpSystemTrace } from '../SpSystemTrace'; +import { TraceRow } from '../trace/base/TraceRow'; -import { BaseStruct } from '../../bean/BaseStruct.js'; +import { BaseStruct } from '../../bean/BaseStruct'; import { queryCounterMax, querySdkCount, querySdkCounterData, querySdkSliceData, queryStartTime, -} from '../../database/SqlLite.js'; -import { CounterStruct, SdkCounterRender } from '../../database/ui-worker/ProduceWorkerSdkCounter.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { SdkSliceRender, SdkSliceStruct } from '../../database/ui-worker/ProduceWorkerSdkSlice.js'; -import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { TabUtil } from '../trace/sheet/sdk/TabUtil.js'; +} from '../../database/SqlLite'; +import { CounterStruct, SdkCounterRender } from '../../database/ui-worker/ProduceWorkerSdkCounter'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { SdkSliceRender, SdkSliceStruct } from '../../database/ui-worker/ProduceWorkerSdkSlice'; +import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { TabUtil } from '../trace/sheet/sdk/TabUtil'; export class SpSdkChart { private trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/SpVirtualMemChart.ts b/ide/src/trace/component/chart/SpVirtualMemChart.ts index 5a2bab899..e1a89df4d 100644 --- a/ide/src/trace/component/chart/SpVirtualMemChart.ts +++ b/ide/src/trace/component/chart/SpVirtualMemChart.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { queryVirtualMemory, queryVirtualMemoryData } from '../../database/SqlLite.js'; -import { VirtualMemoryRender, VirtualMemoryStruct } from '../../database/ui-worker/ProcedureWorkerVirtualMemory.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; +import { SpSystemTrace } from '../SpSystemTrace'; +import { TraceRow } from '../trace/base/TraceRow'; +import { queryVirtualMemory, queryVirtualMemoryData } from '../../database/SqlLite'; +import { VirtualMemoryRender, VirtualMemoryStruct } from '../../database/ui-worker/ProcedureWorkerVirtualMemory'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; export class SpVirtualMemChart { private trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/SpVmTrackerChart.ts b/ide/src/trace/component/chart/SpVmTrackerChart.ts index 4600b2c7e..544f6f69a 100644 --- a/ide/src/trace/component/chart/SpVmTrackerChart.ts +++ b/ide/src/trace/component/chart/SpVmTrackerChart.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { SpSystemTrace } from '../SpSystemTrace.js'; +import { SpSystemTrace } from '../SpSystemTrace'; import { queryDmaSampsData, queryGpuMemoryData, @@ -27,17 +27,17 @@ import { queryGpuWindowType, queryGpuData, queryGpuResourceData, -} from '../../database/SqlLite.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; -import { type BaseStruct } from '../../bean/BaseStruct.js'; -import { renders } from '../../database/ui-worker/ProcedureWorker.js'; -import { Utils } from '../trace/base/Utils.js'; -import { type EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { info } from '../../../log/Log.js'; -import { type SnapshotRender, SnapshotStruct } from '../../database/ui-worker/ProcedureWorkerSnapshot.js'; -import { type TreeItemData } from '../../../base-ui/tree/LitTree.js'; -import { MemoryConfig } from '../../bean/MemoryConfig.js'; -import { TabPaneSmapsRecord } from '../trace/sheet/smaps/TabPaneSmapsRecord.js'; +} from '../../database/SqlLite'; +import { TraceRow } from '../trace/base/TraceRow'; +import { type BaseStruct } from '../../bean/BaseStruct'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { Utils } from '../trace/base/Utils'; +import { type EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { info } from '../../../log/Log'; +import { type SnapshotRender, SnapshotStruct } from '../../database/ui-worker/ProcedureWorkerSnapshot'; +import { type TreeItemData } from '../../../base-ui/tree/LitTree'; +import { MemoryConfig } from '../../bean/MemoryConfig'; +import { TabPaneSmapsRecord } from '../trace/sheet/smaps/TabPaneSmapsRecord'; export class VmTrackerChart { private trace: SpSystemTrace; diff --git a/ide/src/trace/component/chart/VSync.ts b/ide/src/trace/component/chart/VSync.ts index e14509375..1db820567 100644 --- a/ide/src/trace/component/chart/VSync.ts +++ b/ide/src/trace/component/chart/VSync.ts @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { query } from '../../database/SqlLite.js'; -import { TraceRow } from '../trace/base/TraceRow.js'; +import { query } from '../../database/SqlLite'; +import { TraceRow } from '../trace/base/TraceRow'; interface VSyncData { startTime: number; dur: number; diff --git a/ide/src/trace/component/schedulingAnalysis/CheckCpuSetting.ts b/ide/src/trace/component/schedulingAnalysis/CheckCpuSetting.ts index 4643a5e04..f9b1a5450 100644 --- a/ide/src/trace/component/schedulingAnalysis/CheckCpuSetting.ts +++ b/ide/src/trace/component/schedulingAnalysis/CheckCpuSetting.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitCheckBox } from '../../../base-ui/checkbox/LitCheckBox.js'; -import '../../../base-ui/checkbox/LitCheckBox.js'; -import { SpSchedulingAnalysis } from './SpSchedulingAnalysis.js'; -import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitCheckBox } from '../../../base-ui/checkbox/LitCheckBox'; +import '../../../base-ui/checkbox/LitCheckBox'; +import { SpSchedulingAnalysis } from './SpSchedulingAnalysis'; +import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil'; export class CpuSetting { cpu: number = 0; diff --git a/ide/src/trace/component/schedulingAnalysis/DrawerCpuTabs.ts b/ide/src/trace/component/schedulingAnalysis/DrawerCpuTabs.ts index 6545c0f7d..e6432fa1d 100644 --- a/ide/src/trace/component/schedulingAnalysis/DrawerCpuTabs.ts +++ b/ide/src/trace/component/schedulingAnalysis/DrawerCpuTabs.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import './TabCpuDetailsFrequency.js'; -import './TabCpuDetailsIdle.js'; -import './TabCpuDetailsIrq.js'; -import { TabCpuDetailsFrequency } from './TabCpuDetailsFrequency.js'; -import { TabCpuDetailsIdle } from './TabCpuDetailsIdle.js'; -import { LitTabs } from '../../../base-ui/tabs/lit-tabs.js'; -import { TabCpuDetailsIrq } from './TabCpuDetailsIrq.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import './TabCpuDetailsFrequency'; +import './TabCpuDetailsIdle'; +import './TabCpuDetailsIrq'; +import { TabCpuDetailsFrequency } from './TabCpuDetailsFrequency'; +import { TabCpuDetailsIdle } from './TabCpuDetailsIdle'; +import { LitTabs } from '../../../base-ui/tabs/lit-tabs'; +import { TabCpuDetailsIrq } from './TabCpuDetailsIrq'; @element('drawer-cpu-tabs') export class DrawerCpuTabs extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/SpSchedulingAnalysis.ts b/ide/src/trace/component/schedulingAnalysis/SpSchedulingAnalysis.ts index f84503f38..123cf0d84 100644 --- a/ide/src/trace/component/schedulingAnalysis/SpSchedulingAnalysis.ts +++ b/ide/src/trace/component/schedulingAnalysis/SpSchedulingAnalysis.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import './TabThreadAnalysis.js'; -import './TabCpuAnalysis.js'; -import { TabCpuAnalysis } from './TabCpuAnalysis.js'; -import { TabThreadAnalysis } from './TabThreadAnalysis.js'; -import { LitTabs } from '../../../base-ui/tabs/lit-tabs.js'; -import { CheckCpuSetting } from './CheckCpuSetting.js'; -import { Top20FrequencyThread } from './Top20FrequencyThread.js'; -import { procedurePool } from '../../database/Procedure.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import './TabThreadAnalysis'; +import './TabCpuAnalysis'; +import { TabCpuAnalysis } from './TabCpuAnalysis'; +import { TabThreadAnalysis } from './TabThreadAnalysis'; +import { LitTabs } from '../../../base-ui/tabs/lit-tabs'; +import { CheckCpuSetting } from './CheckCpuSetting'; +import { Top20FrequencyThread } from './Top20FrequencyThread'; +import { procedurePool } from '../../database/Procedure'; @element('sp-scheduling-analysis') export class SpSchedulingAnalysis extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuAnalysis.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuAnalysis.ts index 187d14055..ac2ac1a06 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabCpuAnalysis.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuAnalysis.ts @@ -13,20 +13,20 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { SpSchedulingAnalysis } from './SpSchedulingAnalysis.js'; -import { DrawerCpuTabs } from './DrawerCpuTabs.js'; -import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie.js'; -import { LitDrawer } from '../../../base-ui/drawer/LitDrawer.js'; -import '../../../base-ui/drawer/LitDrawer.js'; -import './DrawerCpuTabs.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { info } from '../../../log/Log.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { SpSchedulingAnalysis } from './SpSchedulingAnalysis'; +import { DrawerCpuTabs } from './DrawerCpuTabs'; +import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie'; +import { LitDrawer } from '../../../base-ui/drawer/LitDrawer'; +import '../../../base-ui/drawer/LitDrawer'; +import './DrawerCpuTabs'; +import { procedurePool } from '../../database/Procedure'; +import { info } from '../../../log/Log'; import { LitSelect } from '../../../base-ui/select/LitSelect'; -import '../../../base-ui/progress-bar/LitProgressBar.js'; -import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar.js'; -import { pieChartColors } from '../../../base-ui/chart/pie/LitChartPieData.js'; -import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil.js'; +import '../../../base-ui/progress-bar/LitProgressBar'; +import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; +import { pieChartColors } from '../../../base-ui/chart/pie/LitChartPieData'; +import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil'; @element('tab-cpu-analysis') export class TabCpuAnalysis extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsFrequency.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsFrequency.ts index ea3da89a9..cd2aaaa10 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsFrequency.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsFrequency.ts @@ -13,19 +13,19 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { SpSchedulingAnalysis } from './SpSchedulingAnalysis.js'; -import { TabCpuDetailsThreads } from './TabCpuDetailsThreads.js'; -import './TabCpuDetailsThreads.js'; -import { info } from '../../../log/Log.js'; -import { LitTable } from '../../../base-ui/table/lit-table.js'; -import { getDataNo } from './utils/Utils.js'; -import '../../../base-ui/progress-bar/LitProgressBar.js'; -import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar.js'; -import './TableNoData.js'; -import { TableNoData } from './TableNoData.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie'; +import { procedurePool } from '../../database/Procedure'; +import { SpSchedulingAnalysis } from './SpSchedulingAnalysis'; +import { TabCpuDetailsThreads } from './TabCpuDetailsThreads'; +import './TabCpuDetailsThreads'; +import { info } from '../../../log/Log'; +import { LitTable } from '../../../base-ui/table/lit-table'; +import { getDataNo } from './utils/Utils'; +import '../../../base-ui/progress-bar/LitProgressBar'; +import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; +import './TableNoData'; +import { TableNoData } from './TableNoData'; @element('tab-cpu-details-frequency') export class TabCpuDetailsFrequency extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIdle.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIdle.ts index 1b1239d0c..c9a5c04cf 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIdle.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIdle.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { SpSchedulingAnalysis } from './SpSchedulingAnalysis.js'; -import { info } from '../../../log/Log.js'; -import { LitTable } from '../../../base-ui/table/lit-table.js'; -import '../../../base-ui/progress-bar/LitProgressBar.js'; -import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar.js'; -import { getDataNo } from './utils/Utils.js'; -import './TableNoData.js'; -import { TableNoData } from './TableNoData.js'; -import { pieChartColors } from '../../../base-ui/chart/pie/LitChartPieData.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie'; +import { procedurePool } from '../../database/Procedure'; +import { SpSchedulingAnalysis } from './SpSchedulingAnalysis'; +import { info } from '../../../log/Log'; +import { LitTable } from '../../../base-ui/table/lit-table'; +import '../../../base-ui/progress-bar/LitProgressBar'; +import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; +import { getDataNo } from './utils/Utils'; +import './TableNoData'; +import { TableNoData } from './TableNoData'; +import { pieChartColors } from '../../../base-ui/chart/pie/LitChartPieData'; @element('tab-cpu-details-idle') export class TabCpuDetailsIdle extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIrq.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIrq.ts index 3b6547dd6..85d348191 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIrq.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIrq.ts @@ -13,17 +13,17 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { SpSchedulingAnalysis } from './SpSchedulingAnalysis.js'; -import { info } from '../../../log/Log.js'; -import { LitTable } from '../../../base-ui/table/lit-table.js'; -import '../../../base-ui/progress-bar/LitProgressBar.js'; -import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar.js'; -import { getDataNo } from './utils/Utils.js'; -import './TableNoData.js'; -import { TableNoData } from './TableNoData.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie'; +import { procedurePool } from '../../database/Procedure'; +import { SpSchedulingAnalysis } from './SpSchedulingAnalysis'; +import { info } from '../../../log/Log'; +import { LitTable } from '../../../base-ui/table/lit-table'; +import '../../../base-ui/progress-bar/LitProgressBar'; +import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; +import { getDataNo } from './utils/Utils'; +import './TableNoData'; +import { TableNoData } from './TableNoData'; @element('tab-cpu-details-irq') export class TabCpuDetailsIrq extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsThreads.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsThreads.ts index cdfa3eaf2..67eeb8f09 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsThreads.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsThreads.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { LitTable } from '../../../base-ui/table/lit-table.js'; -import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar.js'; -import '../../../base-ui/progress-bar/LitProgressBar.js'; -import { getDataNo } from './utils/Utils.js'; -import './TableNoData.js'; -import { TableNoData } from './TableNoData.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie'; +import { procedurePool } from '../../database/Procedure'; +import { LitTable } from '../../../base-ui/table/lit-table'; +import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; +import '../../../base-ui/progress-bar/LitProgressBar'; +import { getDataNo } from './utils/Utils'; +import './TableNoData'; +import { TableNoData } from './TableNoData'; @element('tab-cpu-details-threads') export class TabCpuDetailsThreads extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/TabThreadAnalysis.ts b/ide/src/trace/component/schedulingAnalysis/TabThreadAnalysis.ts index 0d5353bc7..f92022a7d 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabThreadAnalysis.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabThreadAnalysis.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import './Top20ThreadCpuUsage.js'; -import './Top20ThreadRunTime.js'; -import './Top20ProcessSwitchCount.js'; -import './Top20ProcessThreadCount.js'; -import './Top20FrequencyThread.js'; -import { Top20ThreadCpuUsage } from './Top20ThreadCpuUsage.js'; -import { Top20ThreadRunTime } from './Top20ThreadRunTime.js'; -import { Top20ProcessThreadCount } from './Top20ProcessThreadCount.js'; -import { Top20ProcessSwitchCount } from './Top20ProcessSwitchCount.js'; -import { Top20FrequencyThread } from './Top20FrequencyThread.js'; -import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import './Top20ThreadCpuUsage'; +import './Top20ThreadRunTime'; +import './Top20ProcessSwitchCount'; +import './Top20ProcessThreadCount'; +import './Top20FrequencyThread'; +import { Top20ThreadCpuUsage } from './Top20ThreadCpuUsage'; +import { Top20ThreadRunTime } from './Top20ThreadRunTime'; +import { Top20ProcessThreadCount } from './Top20ProcessThreadCount'; +import { Top20ProcessSwitchCount } from './Top20ProcessSwitchCount'; +import { Top20FrequencyThread } from './Top20FrequencyThread'; +import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil'; @element('tab-thread-analysis') export class TabThreadAnalysis extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/TableNoData.ts b/ide/src/trace/component/schedulingAnalysis/TableNoData.ts index 0666c9fef..dbc00f399 100644 --- a/ide/src/trace/component/schedulingAnalysis/TableNoData.ts +++ b/ide/src/trace/component/schedulingAnalysis/TableNoData.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; @element('table-no-data') export class TableNoData extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/Top20FrequencyThread.ts b/ide/src/trace/component/schedulingAnalysis/Top20FrequencyThread.ts index a04d17627..8791963a5 100644 --- a/ide/src/trace/component/schedulingAnalysis/Top20FrequencyThread.ts +++ b/ide/src/trace/component/schedulingAnalysis/Top20FrequencyThread.ts @@ -13,20 +13,20 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../base-ui/table/lit-table.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { info } from '../../../log/Log.js'; -import '../../../base-ui/chart/pie/LitChartPie.js'; -import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie.js'; -import { LitSelect } from '../../../base-ui/select/LitSelect.js'; -import { queryThreads } from '../../database/SqlLite.js'; -import { LitSelectOption } from '../../../base-ui/select/LitSelectOption.js'; -import '../../../base-ui/progress-bar/LitProgressBar.js'; -import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar.js'; -import './TableNoData.js'; -import { TableNoData } from './TableNoData.js'; -import { getProbablyTime } from '../../database/logic-worker/ProcedureLogicWorkerCommon.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitTable } from '../../../base-ui/table/lit-table'; +import { procedurePool } from '../../database/Procedure'; +import { info } from '../../../log/Log'; +import '../../../base-ui/chart/pie/LitChartPie'; +import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie'; +import { LitSelect } from '../../../base-ui/select/LitSelect'; +import { queryThreads } from '../../database/SqlLite'; +import { LitSelectOption } from '../../../base-ui/select/LitSelectOption'; +import '../../../base-ui/progress-bar/LitProgressBar'; +import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; +import './TableNoData'; +import { TableNoData } from './TableNoData'; +import { getProbablyTime } from '../../database/logic-worker/ProcedureLogicWorkerCommon'; @element('top20-frequency-thread') export class Top20FrequencyThread extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/Top20ProcessSwitchCount.ts b/ide/src/trace/component/schedulingAnalysis/Top20ProcessSwitchCount.ts index bfcf7f170..a6535146a 100644 --- a/ide/src/trace/component/schedulingAnalysis/Top20ProcessSwitchCount.ts +++ b/ide/src/trace/component/schedulingAnalysis/Top20ProcessSwitchCount.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../base-ui/table/lit-table.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { info } from '../../../log/Log.js'; -import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie.js'; -import '../../../base-ui/progress-bar/LitProgressBar.js'; -import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar.js'; -import './TableNoData.js'; -import { TableNoData } from './TableNoData.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitTable } from '../../../base-ui/table/lit-table'; +import { procedurePool } from '../../database/Procedure'; +import { info } from '../../../log/Log'; +import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie'; +import '../../../base-ui/progress-bar/LitProgressBar'; +import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; +import './TableNoData'; +import { TableNoData } from './TableNoData'; @element('top20-process-switch-count') export class Top20ProcessSwitchCount extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/Top20ProcessThreadCount.ts b/ide/src/trace/component/schedulingAnalysis/Top20ProcessThreadCount.ts index 235aa457d..5d3296977 100644 --- a/ide/src/trace/component/schedulingAnalysis/Top20ProcessThreadCount.ts +++ b/ide/src/trace/component/schedulingAnalysis/Top20ProcessThreadCount.ts @@ -13,16 +13,16 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../base-ui/table/lit-table.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { info } from '../../../log/Log.js'; -import '../../../base-ui/chart/pie/LitChartPie.js'; -import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie.js'; -import '../../../base-ui/progress-bar/LitProgressBar.js'; -import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar.js'; -import './TableNoData.js'; -import { TableNoData } from './TableNoData.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitTable } from '../../../base-ui/table/lit-table'; +import { procedurePool } from '../../database/Procedure'; +import { info } from '../../../log/Log'; +import '../../../base-ui/chart/pie/LitChartPie'; +import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie'; +import '../../../base-ui/progress-bar/LitProgressBar'; +import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; +import './TableNoData'; +import { TableNoData } from './TableNoData'; @element('top20-process-thread-count') export class Top20ProcessThreadCount extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/Top20ThreadCpuUsage.ts b/ide/src/trace/component/schedulingAnalysis/Top20ThreadCpuUsage.ts index a698bb334..b2466e34e 100644 --- a/ide/src/trace/component/schedulingAnalysis/Top20ThreadCpuUsage.ts +++ b/ide/src/trace/component/schedulingAnalysis/Top20ThreadCpuUsage.ts @@ -13,21 +13,21 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../base-ui/table/lit-table.js'; -import { LitChartColumn } from '../../../base-ui/chart/column/LitChartColumn.js'; -import '../../../base-ui/chart/column/LitChartColumn.js'; -import './CheckCpuSetting.js'; -import '../../../base-ui/icon/LitIcon.js'; -import { CheckCpuSetting } from './CheckCpuSetting.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { info } from '../../../log/Log.js'; -import '../../../base-ui/progress-bar/LitProgressBar.js'; -import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar.js'; -import './TableNoData.js'; -import { TableNoData } from './TableNoData.js'; -import { getProbablyTime } from '../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { SpSchedulingAnalysis } from './SpSchedulingAnalysis.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitTable } from '../../../base-ui/table/lit-table'; +import { LitChartColumn } from '../../../base-ui/chart/column/LitChartColumn'; +import '../../../base-ui/chart/column/LitChartColumn'; +import './CheckCpuSetting'; +import '../../../base-ui/icon/LitIcon'; +import { CheckCpuSetting } from './CheckCpuSetting'; +import { procedurePool } from '../../database/Procedure'; +import { info } from '../../../log/Log'; +import '../../../base-ui/progress-bar/LitProgressBar'; +import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; +import './TableNoData'; +import { TableNoData } from './TableNoData'; +import { getProbablyTime } from '../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { SpSchedulingAnalysis } from './SpSchedulingAnalysis'; @element('top20-thread-cpu-usage') export class Top20ThreadCpuUsage extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/Top20ThreadRunTime.ts b/ide/src/trace/component/schedulingAnalysis/Top20ThreadRunTime.ts index eb51e2fff..dbd1c6d6b 100644 --- a/ide/src/trace/component/schedulingAnalysis/Top20ThreadRunTime.ts +++ b/ide/src/trace/component/schedulingAnalysis/Top20ThreadRunTime.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../base-ui/table/lit-table.js'; -import { SpSchedulingAnalysis } from './SpSchedulingAnalysis.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { info } from '../../../log/Log.js'; -import '../../../base-ui/progress-bar/LitProgressBar.js'; -import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar.js'; -import './TableNoData.js'; -import { TableNoData } from './TableNoData.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitTable } from '../../../base-ui/table/lit-table'; +import { SpSchedulingAnalysis } from './SpSchedulingAnalysis'; +import { procedurePool } from '../../database/Procedure'; +import { info } from '../../../log/Log'; +import '../../../base-ui/progress-bar/LitProgressBar'; +import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; +import './TableNoData'; +import { TableNoData } from './TableNoData'; @element('top20-thread-run-time') export class Top20ThreadRunTime extends BaseElement { diff --git a/ide/src/trace/component/schedulingAnalysis/utils/Utils.ts b/ide/src/trace/component/schedulingAnalysis/utils/Utils.ts index c0d40eb6d..3dc44e328 100644 --- a/ide/src/trace/component/schedulingAnalysis/utils/Utils.ts +++ b/ide/src/trace/component/schedulingAnalysis/utils/Utils.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { Utils } from '../../trace/base/Utils.js'; +import { Utils } from '../../trace/base/Utils'; export const getFormatData = (data: Array) => { let arrData: Array = []; diff --git a/ide/src/trace/component/setting/SpAllocations.ts b/ide/src/trace/component/setting/SpAllocations.ts index 2f65c50b8..29f011429 100644 --- a/ide/src/trace/component/setting/SpAllocations.ts +++ b/ide/src/trace/component/setting/SpAllocations.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { log } from '../../../log/Log.js'; -import { SpApplication } from '../../SpApplication.js'; -import { LitSearch } from '../trace/search/Search.js'; -import { SpRecordTrace } from '../SpRecordTrace.js'; -import { Cmd } from '../../../command/Cmd.js'; -import LitSwitch from '../../../base-ui/switch/lit-switch.js'; -import { LitSlider } from '../../../base-ui/slider/LitSlider.js'; -import { LitSelectV } from '../../../base-ui/select/LitSelectV.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { log } from '../../../log/Log'; +import { SpApplication } from '../../SpApplication'; +import { LitSearch } from '../trace/search/Search'; +import { SpRecordTrace } from '../SpRecordTrace'; +import { Cmd } from '../../../command/Cmd'; +import LitSwitch from '../../../base-ui/switch/lit-switch'; +import { LitSlider } from '../../../base-ui/slider/LitSlider'; +import { LitSelectV } from '../../../base-ui/select/LitSelectV'; @element('sp-allocations') export class SpAllocations extends BaseElement { diff --git a/ide/src/trace/component/setting/SpArkTs.ts b/ide/src/trace/component/setting/SpArkTs.ts index c081c43d8..836360ebe 100644 --- a/ide/src/trace/component/setting/SpArkTs.ts +++ b/ide/src/trace/component/setting/SpArkTs.ts @@ -13,17 +13,17 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import '../../../base-ui/select/LitAllocationSelect.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import '../../../base-ui/select/LitAllocationSelect'; -import '../../../base-ui/switch/lit-switch.js'; -import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect.js'; -import { SpRecordTrace } from '../SpRecordTrace.js'; -import { Cmd } from '../../../command/Cmd.js'; -import { LitRadioBox } from '../../../base-ui/radiobox/LitRadioBox.js'; -import { SpCheckDesBox } from './SpCheckDesBox.js'; -import LitSwitch from '../../../base-ui/switch/lit-switch.js'; -import { SpApplication } from '../../SpApplication.js'; +import '../../../base-ui/switch/lit-switch'; +import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect'; +import { SpRecordTrace } from '../SpRecordTrace'; +import { Cmd } from '../../../command/Cmd'; +import { LitRadioBox } from '../../../base-ui/radiobox/LitRadioBox'; +import { SpCheckDesBox } from './SpCheckDesBox'; +import LitSwitch from '../../../base-ui/switch/lit-switch'; +import { SpApplication } from '../../SpApplication'; @element('sp-ark-ts') export class SpArkTs extends BaseElement { diff --git a/ide/src/trace/component/setting/SpCheckDesBox.ts b/ide/src/trace/component/setting/SpCheckDesBox.ts index 9a950e715..d1c0977d2 100644 --- a/ide/src/trace/component/setting/SpCheckDesBox.ts +++ b/ide/src/trace/component/setting/SpCheckDesBox.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitCheckBox, LitCheckBoxChangeEvent } from '../../../base-ui/checkbox/LitCheckBox.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitCheckBox, LitCheckBoxChangeEvent } from '../../../base-ui/checkbox/LitCheckBox'; @element('check-des-box') export class SpCheckDesBox extends BaseElement { diff --git a/ide/src/trace/component/setting/SpFileSystem.ts b/ide/src/trace/component/setting/SpFileSystem.ts index 716a4df7b..0a1cce88f 100644 --- a/ide/src/trace/component/setting/SpFileSystem.ts +++ b/ide/src/trace/component/setting/SpFileSystem.ts @@ -13,19 +13,19 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitSelectV } from '../../../base-ui/select/LitSelectV.js'; -import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch.js'; -import '../../../base-ui/select/LitSelectV.js'; -import '../../../base-ui/select/LitSelect.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitSelectV } from '../../../base-ui/select/LitSelectV'; +import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch'; +import '../../../base-ui/select/LitSelectV'; +import '../../../base-ui/select/LitSelect'; -import '../../../base-ui/switch/lit-switch.js'; -import { LitSelect } from '../../../base-ui/select/LitSelect.js'; -import { SpRecordTrace } from '../SpRecordTrace.js'; -import { Cmd } from '../../../command/Cmd.js'; -import { CmdConstant } from '../../../command/CmdConstant.js'; -import { HdcDeviceManager } from '../../../hdc/HdcDeviceManager.js'; -import { SpApplication } from '../../SpApplication.js'; +import '../../../base-ui/switch/lit-switch'; +import { LitSelect } from '../../../base-ui/select/LitSelect'; +import { SpRecordTrace } from '../SpRecordTrace'; +import { Cmd } from '../../../command/Cmd'; +import { CmdConstant } from '../../../command/CmdConstant'; +import { HdcDeviceManager } from '../../../hdc/HdcDeviceManager'; +import { SpApplication } from '../../SpApplication'; @element('sp-file-system') export class SpFileSystem extends BaseElement { diff --git a/ide/src/trace/component/setting/SpHilogRecord.ts b/ide/src/trace/component/setting/SpHilogRecord.ts index fbb07bd80..ce0dba914 100644 --- a/ide/src/trace/component/setting/SpHilogRecord.ts +++ b/ide/src/trace/component/setting/SpHilogRecord.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import LitSwitch from '../../../base-ui/switch/lit-switch.js'; -import '../../../base-ui/select/LitAllocationSelect.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import LitSwitch from '../../../base-ui/switch/lit-switch'; +import '../../../base-ui/select/LitAllocationSelect'; -import '../../../base-ui/switch/lit-switch.js'; -import { SpRecordTrace } from '../SpRecordTrace.js'; -import { Cmd } from '../../../command/Cmd.js'; -import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect.js'; -import { LitSelect } from '../../../base-ui/select/LitSelect.js'; +import '../../../base-ui/switch/lit-switch'; +import { SpRecordTrace } from '../SpRecordTrace'; +import { Cmd } from '../../../command/Cmd'; +import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect'; +import { LitSelect } from '../../../base-ui/select/LitSelect'; @element('sp-hi-log') export class SpHilogRecord extends BaseElement { diff --git a/ide/src/trace/component/setting/SpHisysEvent.ts b/ide/src/trace/component/setting/SpHisysEvent.ts index 154c68483..647cce95b 100644 --- a/ide/src/trace/component/setting/SpHisysEvent.ts +++ b/ide/src/trace/component/setting/SpHisysEvent.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch.js'; -import '../../../base-ui/select/LitAllocationSelect.js'; -import '../../../base-ui/switch/lit-switch.js'; -import { SpRecordTrace } from '../SpRecordTrace.js'; -import { HdcDeviceManager } from '../../../hdc/HdcDeviceManager.js'; -import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch'; +import '../../../base-ui/select/LitAllocationSelect'; +import '../../../base-ui/switch/lit-switch'; +import { SpRecordTrace } from '../SpRecordTrace'; +import { HdcDeviceManager } from '../../../hdc/HdcDeviceManager'; +import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect'; @element('sp-hisys-event') export class SpHisysEvent extends BaseElement { diff --git a/ide/src/trace/component/setting/SpProbesConfig.ts b/ide/src/trace/component/setting/SpProbesConfig.ts index 83e799a54..d3f3582e2 100644 --- a/ide/src/trace/component/setting/SpProbesConfig.ts +++ b/ide/src/trace/component/setting/SpProbesConfig.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { checkDesBean, SpCheckDesBox } from './SpCheckDesBox.js'; -import { LitCheckBox, LitCheckBoxChangeEvent } from '../../../base-ui/checkbox/LitCheckBox.js'; -import { LitRadioGroup } from '../../../base-ui/radiobox/LitRadioGroup.js'; -import { info, log } from '../../../log/Log.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { checkDesBean, SpCheckDesBox } from './SpCheckDesBox'; +import { LitCheckBox, LitCheckBoxChangeEvent } from '../../../base-ui/checkbox/LitCheckBox'; +import { LitRadioGroup } from '../../../base-ui/radiobox/LitRadioGroup'; +import { info, log } from '../../../log/Log'; import { LitSlider } from '../../../base-ui/slider/LitSlider'; -import LitSwitch from '../../../base-ui/switch/lit-switch.js'; +import LitSwitch from '../../../base-ui/switch/lit-switch'; @element('probes-config') export class SpProbesConfig extends BaseElement { diff --git a/ide/src/trace/component/setting/SpRecordPerf.ts b/ide/src/trace/component/setting/SpRecordPerf.ts index 8fae2ddca..5c17d0286 100644 --- a/ide/src/trace/component/setting/SpRecordPerf.ts +++ b/ide/src/trace/component/setting/SpRecordPerf.ts @@ -13,22 +13,22 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { LitSelectV } from '../../../base-ui/select/LitSelectV.js'; -import { LitSelect } from '../../../base-ui/select/LitSelect.js'; -import { LitSlider } from '../../../base-ui/slider/LitSlider.js'; -import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch.js'; -import '../../../base-ui/select/LitSelectV.js'; -import '../../../base-ui/select/LitSelect.js'; - -import '../../../base-ui/switch/lit-switch.js'; -import { info } from '../../../log/Log.js'; -import { HdcDeviceManager } from '../../../hdc/HdcDeviceManager.js'; -import { SpRecordTrace } from '../SpRecordTrace.js'; -import { SpApplication } from '../../SpApplication.js'; -import { LitSearch } from '../trace/search/Search.js'; -import { Cmd } from '../../../command/Cmd.js'; -import { CmdConstant } from '../../../command/CmdConstant.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { LitSelectV } from '../../../base-ui/select/LitSelectV'; +import { LitSelect } from '../../../base-ui/select/LitSelect'; +import { LitSlider } from '../../../base-ui/slider/LitSlider'; +import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch'; +import '../../../base-ui/select/LitSelectV'; +import '../../../base-ui/select/LitSelect'; + +import '../../../base-ui/switch/lit-switch'; +import { info } from '../../../log/Log'; +import { HdcDeviceManager } from '../../../hdc/HdcDeviceManager'; +import { SpRecordTrace } from '../SpRecordTrace'; +import { SpApplication } from '../../SpApplication'; +import { LitSearch } from '../trace/search/Search'; +import { Cmd } from '../../../command/Cmd'; +import { CmdConstant } from '../../../command/CmdConstant'; @element('sp-record-perf') export class SpRecordPerf extends BaseElement { diff --git a/ide/src/trace/component/setting/SpRecordSetting.ts b/ide/src/trace/component/setting/SpRecordSetting.ts index 0421f3630..cafce6e1b 100644 --- a/ide/src/trace/component/setting/SpRecordSetting.ts +++ b/ide/src/trace/component/setting/SpRecordSetting.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import '../../../base-ui/radiobox/LitRadioBox.js'; -import { LitRadioBox } from '../../../base-ui/radiobox/LitRadioBox.js'; -import '../../../base-ui/slider/LitSlider.js'; -import { LitSlider } from '../../../base-ui/slider/LitSlider.js'; -import '../../../base-ui/popover/LitPopover.js'; -import { info } from '../../../log/Log.js'; -import { SpApplication } from '../../SpApplication.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import '../../../base-ui/radiobox/LitRadioBox'; +import { LitRadioBox } from '../../../base-ui/radiobox/LitRadioBox'; +import '../../../base-ui/slider/LitSlider'; +import { LitSlider } from '../../../base-ui/slider/LitSlider'; +import '../../../base-ui/popover/LitPopover'; +import { info } from '../../../log/Log'; +import { SpApplication } from '../../SpApplication'; @element('record-setting') export class SpRecordSetting extends BaseElement { diff --git a/ide/src/trace/component/setting/SpRecordTemplate.ts b/ide/src/trace/component/setting/SpRecordTemplate.ts index f30c3e8fe..ea64abc86 100644 --- a/ide/src/trace/component/setting/SpRecordTemplate.ts +++ b/ide/src/trace/component/setting/SpRecordTemplate.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch.js'; -import { HiperfPluginConfig, ProfilerPluginConfig, TracePluginConfig } from './bean/ProfilerServiceTypes.js'; -import { SpRecordTrace } from '../SpRecordTrace.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch'; +import { HiperfPluginConfig, ProfilerPluginConfig, TracePluginConfig } from './bean/ProfilerServiceTypes'; +import { SpRecordTrace } from '../SpRecordTrace'; @element('sp-record-template') export class SpRecordTemplate extends BaseElement { diff --git a/ide/src/trace/component/setting/SpSdkConfig.ts b/ide/src/trace/component/setting/SpSdkConfig.ts index 9e47432a5..1dd786601 100644 --- a/ide/src/trace/component/setting/SpSdkConfig.ts +++ b/ide/src/trace/component/setting/SpSdkConfig.ts @@ -13,15 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import '../../../base-ui/select/LitSelectV.js'; -import '../../../base-ui/select/LitSelect.js'; - -import '../../../base-ui/switch/lit-switch.js'; -import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch.js'; -import { LitSelectV } from '../../../base-ui/select/LitSelectV.js'; -import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import '../../../base-ui/select/LitSelectV'; +import '../../../base-ui/select/LitSelect'; +import '../../../base-ui/switch/lit-switch'; +import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch'; +import { LitSelectV } from '../../../base-ui/select/LitSelectV'; +import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect'; @element('sp-sdk-config') export class SpSdkConfig extends BaseElement { private worker: Worker | undefined; @@ -168,7 +167,8 @@ export class SpSdkConfig extends BaseElement { if (window.useWb) { return; } - this.worker = new Worker('trace/database/ConfigWorker.js'); + + this.worker = new Worker(new URL('../../database/ConfigWorker',import.meta.url)); } } catch (e) {} this.customConfig = this.shadowRoot?.querySelector('.configList'); diff --git a/ide/src/trace/component/setting/SpTraceCommand.ts b/ide/src/trace/component/setting/SpTraceCommand.ts index 4965e7e78..03cb8d601 100644 --- a/ide/src/trace/component/setting/SpTraceCommand.ts +++ b/ide/src/trace/component/setting/SpTraceCommand.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { info } from '../../../log/Log.js'; -import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil.js'; -import { PluginConvertUtils } from './utils/PluginConvertUtils.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { info } from '../../../log/Log'; +import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil'; +import { PluginConvertUtils } from './utils/PluginConvertUtils'; @element('trace-command') export class SpTraceCommand extends BaseElement { diff --git a/ide/src/trace/component/setting/SpVmTracker.ts b/ide/src/trace/component/setting/SpVmTracker.ts index 81dec5e24..02020beaf 100644 --- a/ide/src/trace/component/setting/SpVmTracker.ts +++ b/ide/src/trace/component/setting/SpVmTracker.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch.js'; -import '../../../base-ui/select/LitAllocationSelect.js'; - -import '../../../base-ui/switch/lit-switch.js'; -import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect.js'; -import { SpRecordTrace } from '../SpRecordTrace.js'; -import { Cmd } from '../../../command/Cmd.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch'; +import '../../../base-ui/select/LitAllocationSelect'; + +import '../../../base-ui/switch/lit-switch'; +import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect'; +import { SpRecordTrace } from '../SpRecordTrace'; +import { Cmd } from '../../../command/Cmd'; @element('sp-vm-tracker') export class SpVmTracker extends BaseElement { diff --git a/ide/src/trace/component/setting/SpWebHdcShell.ts b/ide/src/trace/component/setting/SpWebHdcShell.ts index 447cdca7c..55e89d8d8 100644 --- a/ide/src/trace/component/setting/SpWebHdcShell.ts +++ b/ide/src/trace/component/setting/SpWebHdcShell.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { HdcDeviceManager } from '../../../hdc/HdcDeviceManager.js'; -import { SpRecordTrace } from '../SpRecordTrace.js'; -import { DataMessage } from '../../../hdc/message/DataMessage.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { HdcDeviceManager } from '../../../hdc/HdcDeviceManager'; +import { SpRecordTrace } from '../SpRecordTrace'; +import { DataMessage } from '../../../hdc/message/DataMessage'; @element('sp-web-hdc-shell') export class SpWebHdcShell extends BaseElement { diff --git a/ide/src/trace/component/trace/SpChartList.ts b/ide/src/trace/component/trace/SpChartList.ts index c95af098f..6036253c4 100644 --- a/ide/src/trace/component/trace/SpChartList.ts +++ b/ide/src/trace/component/trace/SpChartList.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { TraceRow } from './base/TraceRow.js'; -import { dpr } from './base/Extension.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { TraceRow } from './base/TraceRow'; +import { dpr } from './base/Extension'; import { drawFlagLineSegment, drawLines, @@ -25,13 +25,13 @@ import { drawWakeUpList, PairPoint, Rect, -} from '../../database/ui-worker/ProcedureWorkerCommon.js'; -import { Flag } from './timer-shaft/Flag.js'; -import { TimerShaftElement } from './TimerShaftElement.js'; -import { CpuStruct } from '../../database/ui-worker/ProcedureWorkerCPU.js'; -import { WakeupBean } from '../../bean/WakeupBean.js'; -import { LitIcon } from '../../../base-ui/icon/LitIcon.js'; -import { drawVSync } from '../chart/VSync.js'; +} from '../../database/ui-worker/ProcedureWorkerCommon'; +import { Flag } from './timer-shaft/Flag'; +import { TimerShaftElement } from './TimerShaftElement'; +import { CpuStruct } from '../../database/ui-worker/ProcedureWorkerCPU'; +import { WakeupBean } from '../../bean/WakeupBean'; +import { LitIcon } from '../../../base-ui/icon/LitIcon'; +import { drawVSync } from '../chart/VSync'; const maxScale = 0.8; //收藏最大高度为界面最大高度的80% const topHeight = 150; // 顶部cpu使用率部分高度固定为150px diff --git a/ide/src/trace/component/trace/TimerShaftElement.ts b/ide/src/trace/component/trace/TimerShaftElement.ts index 04d232573..e30564187 100644 --- a/ide/src/trace/component/trace/TimerShaftElement.ts +++ b/ide/src/trace/component/trace/TimerShaftElement.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../base-ui/BaseElement.js'; -import { TimeRuler } from './timer-shaft/TimeRuler.js'; -import { Rect } from './timer-shaft/Rect.js'; -import { RangeRuler, TimeRange } from './timer-shaft/RangeRuler.js'; -import { SlicesTime, SportRuler } from './timer-shaft/SportRuler.js'; -import { procedurePool } from '../../database/Procedure.js'; -import { Flag } from './timer-shaft/Flag.js'; -import { info } from '../../../log/Log.js'; -import { TraceSheet } from './base/TraceSheet.js'; -import { SelectionParam } from '../../bean/BoxSelection.js'; -import { type SpSystemTrace, CurrentSlicesTime } from '../SpSystemTrace.js'; -import './timer-shaft/CollapseButton.js'; +import { BaseElement, element } from '../../../base-ui/BaseElement'; +import { TimeRuler } from './timer-shaft/TimeRuler'; +import { Rect } from './timer-shaft/Rect'; +import { RangeRuler, TimeRange } from './timer-shaft/RangeRuler'; +import { SlicesTime, SportRuler } from './timer-shaft/SportRuler'; +import { procedurePool } from '../../database/Procedure'; +import { Flag } from './timer-shaft/Flag'; +import { info } from '../../../log/Log'; +import { TraceSheet } from './base/TraceSheet'; +import { SelectionParam } from '../../bean/BoxSelection'; +import { type SpSystemTrace, CurrentSlicesTime } from '../SpSystemTrace'; +import './timer-shaft/CollapseButton'; //随机生成十六位进制颜色 export function randomRgbColor() { let r = Math.floor(Math.random() * 255); diff --git a/ide/src/trace/component/trace/base/ColorUtils.ts b/ide/src/trace/component/trace/base/ColorUtils.ts index c3c75ef11..e2046a2b0 100644 --- a/ide/src/trace/component/trace/base/ColorUtils.ts +++ b/ide/src/trace/component/trace/base/ColorUtils.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU.js'; +import { CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU'; export class ColorUtils { public static GREY_COLOR: string = '#f0f0f0'; diff --git a/ide/src/trace/component/trace/base/CustomThemeColor.ts b/ide/src/trace/component/trace/base/CustomThemeColor.ts index f743e9573..762cc311e 100644 --- a/ide/src/trace/component/trace/base/CustomThemeColor.ts +++ b/ide/src/trace/component/trace/base/CustomThemeColor.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; -import { ColorUtils } from './ColorUtils.js'; -import { LitRadioBox } from '../../../../base-ui/radiobox/LitRadioBox.js'; -import { SpApplication } from '../../../SpApplication.js'; -import { SpSystemTrace } from '../../SpSystemTrace.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; +import { ColorUtils } from './ColorUtils'; +import { LitRadioBox } from '../../../../base-ui/radiobox/LitRadioBox'; +import { SpApplication } from '../../../SpApplication'; +import { SpSystemTrace } from '../../SpSystemTrace'; @element('custom-theme-color') export class CustomThemeColor extends BaseElement { diff --git a/ide/src/trace/component/trace/base/Extension.ts b/ide/src/trace/component/trace/base/Extension.ts index 6373d2c30..eb01c169d 100644 --- a/ide/src/trace/component/trace/base/Extension.ts +++ b/ide/src/trace/component/trace/base/Extension.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { EventCenter } from './EventCenter.js'; +import { EventCenter } from './EventCenter'; declare global { interface Number { diff --git a/ide/src/trace/component/trace/base/RangeSelect.ts b/ide/src/trace/component/trace/base/RangeSelect.ts index f6c7ebc3d..a224e5967 100644 --- a/ide/src/trace/component/trace/base/RangeSelect.ts +++ b/ide/src/trace/component/trace/base/RangeSelect.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { RangeSelectStruct, TraceRow } from './TraceRow.js'; -import { Rect } from '../timer-shaft/Rect.js'; -import { ns2x, TimerShaftElement } from '../TimerShaftElement.js'; -import { info } from '../../../../log/Log.js'; -import './Extension.js'; -import { SpSystemTrace } from '../../SpSystemTrace.js'; -import { querySearchRowFuncData } from '../../../database/SqlLite.js'; +import { RangeSelectStruct, TraceRow } from './TraceRow'; +import { Rect } from '../timer-shaft/Rect'; +import { ns2x, TimerShaftElement } from '../TimerShaftElement'; +import { info } from '../../../../log/Log'; +import './Extension'; +import { SpSystemTrace } from '../../SpSystemTrace'; +import { querySearchRowFuncData } from '../../../database/SqlLite'; export class RangeSelect { private rowsEL: HTMLDivElement | undefined | null; diff --git a/ide/src/trace/component/trace/base/TraceRow.ts b/ide/src/trace/component/trace/base/TraceRow.ts index dbe9b0a30..097d62414 100644 --- a/ide/src/trace/component/trace/base/TraceRow.ts +++ b/ide/src/trace/component/trace/base/TraceRow.ts @@ -13,23 +13,23 @@ * limitations under the License. */ -import { element } from '../../../../base-ui/BaseElement.js'; -import { TimeRange } from '../timer-shaft/RangeRuler.js'; -import '../../../../base-ui/icon/LitIcon.js'; -import { Rect } from '../timer-shaft/Rect.js'; -import { BaseStruct } from '../../../bean/BaseStruct.js'; -import { ns2x } from '../TimerShaftElement.js'; -import { TraceRowObject } from './TraceRowObject.js'; -import { LitCheckBox } from '../../../../base-ui/checkbox/LitCheckBox.js'; +import { element } from '../../../../base-ui/BaseElement'; +import { TimeRange } from '../timer-shaft/RangeRuler'; +import '../../../../base-ui/icon/LitIcon'; +import { Rect } from '../timer-shaft/Rect'; +import { BaseStruct } from '../../../bean/BaseStruct'; +import { ns2x } from '../TimerShaftElement'; +import { TraceRowObject } from './TraceRowObject'; +import { LitCheckBox } from '../../../../base-ui/checkbox/LitCheckBox'; import { LitIcon } from '../../../../base-ui/icon/LitIcon'; -import '../../../../base-ui/popover/LitPopoverV.js'; -import '../../../../base-ui/tree/LitTree.js'; -import { LitPopover } from '../../../../base-ui/popover/LitPopoverV.js'; -import { info } from '../../../../log/Log.js'; -import { ColorUtils } from './ColorUtils.js'; -import { drawSelectionRange, isFrameContainPoint } from '../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { TraceRowConfig } from './TraceRowConfig.js'; -import { type TreeItemData, LitTree } from '../../../../base-ui/tree/LitTree.js'; +import '../../../../base-ui/popover/LitPopoverV'; +import '../../../../base-ui/tree/LitTree'; +import { LitPopover } from '../../../../base-ui/popover/LitPopoverV'; +import { info } from '../../../../log/Log'; +import { ColorUtils } from './ColorUtils'; +import { drawSelectionRange, isFrameContainPoint } from '../../../database/ui-worker/ProcedureWorkerCommon'; +import { TraceRowConfig } from './TraceRowConfig'; +import { type TreeItemData, LitTree } from '../../../../base-ui/tree/LitTree'; export class RangeSelectStruct { startX: number | undefined; @@ -215,6 +215,7 @@ export class TraceRow extends HTMLElement { static get observedAttributes() { return [ 'folder', + 'sticky', 'name', 'expansion', 'children', @@ -249,7 +250,16 @@ export class TraceRow extends HTMLElement { set funcExpand(b: boolean) { this.setAttribute('func-expand', b ? 'true' : 'false'); } - + get sticky():boolean{ + return this.hasAttribute('sticky'); + } + set sticky(fixed:boolean){ + if (fixed) { + this.setAttribute('sticky', ''); + }else{ + this.removeAttribute('sticky'); + } + } get hasParentRowEl(): boolean { return this.parentRowEl !== undefined; } @@ -690,6 +700,7 @@ export class TraceRow extends HTMLElement { this.describeEl?.addEventListener('click', () => { if (this.folder) { this.expansion = !this.expansion; + this.sticky = this.expansion; } }); this.funcExpand = true; @@ -1287,6 +1298,11 @@ export class TraceRow extends HTMLElement { :host(:not([folder])[children]) .name{ } + :host([sticky]) { + position: sticky; + top: 0; + z-index: 999; + } :host([expansion]) { background-color: var(--bark-expansion,#0C65D1); } diff --git a/ide/src/trace/component/trace/base/TraceRowConfig.ts b/ide/src/trace/component/trace/base/TraceRowConfig.ts index f41dd593f..ef8814805 100644 --- a/ide/src/trace/component/trace/base/TraceRowConfig.ts +++ b/ide/src/trace/component/trace/base/TraceRowConfig.ts @@ -13,16 +13,16 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; -import '../../../../base-ui/checkbox/LitCheckBox.js'; -import { LitCheckBox } from '../../../../base-ui/checkbox/LitCheckBox.js'; -import { TraceRow } from './TraceRow.js'; -import { SpSystemTrace } from '../../SpSystemTrace.js'; -import { LitSearch } from '../search/Search.js'; -import { TraceSheet } from './TraceSheet.js'; -import { CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU.js'; -import { type BaseStruct } from '../../../bean/BaseStruct.js'; -import { LitIcon } from '../../../../base-ui/icon/LitIcon.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; +import '../../../../base-ui/checkbox/LitCheckBox'; +import { LitCheckBox } from '../../../../base-ui/checkbox/LitCheckBox'; +import { TraceRow } from './TraceRow'; +import { SpSystemTrace } from '../../SpSystemTrace'; +import { LitSearch } from '../search/Search'; +import { TraceSheet } from './TraceSheet'; +import { CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU'; +import { type BaseStruct } from '../../../bean/BaseStruct'; +import { LitIcon } from '../../../../base-ui/icon/LitIcon'; @element('trace-row-config') export class TraceRowConfig extends BaseElement { diff --git a/ide/src/trace/component/trace/base/TraceRowObject.ts b/ide/src/trace/component/trace/base/TraceRowObject.ts index 22cd59520..bb51910fa 100644 --- a/ide/src/trace/component/trace/base/TraceRowObject.ts +++ b/ide/src/trace/component/trace/base/TraceRowObject.ts @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseStruct } from '../../../bean/BaseStruct.js'; -import { Rect } from '../timer-shaft/Rect.js'; -import { TraceRow } from './TraceRow.js'; +import { BaseStruct } from '../../../bean/BaseStruct'; +import { Rect } from '../timer-shaft/Rect'; +import { TraceRow } from './TraceRow'; export class TraceRowObject { public rowId: string | undefined; diff --git a/ide/src/trace/component/trace/base/TraceRowRecyclerView.ts b/ide/src/trace/component/trace/base/TraceRowRecyclerView.ts index 6b2427486..8efa35831 100644 --- a/ide/src/trace/component/trace/base/TraceRowRecyclerView.ts +++ b/ide/src/trace/component/trace/base/TraceRowRecyclerView.ts @@ -12,10 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; -import { TraceRowObject } from './TraceRowObject.js'; -import { TraceRow } from './TraceRow.js'; -import { log } from '../../../../log/Log.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; +import { TraceRowObject } from './TraceRowObject'; +import { TraceRow } from './TraceRow'; +import { log } from '../../../../log/Log'; @element('trace-row-recycler-view') export class TraceRowRecyclerView extends BaseElement { diff --git a/ide/src/trace/component/trace/base/TraceSheet.ts b/ide/src/trace/component/trace/base/TraceSheet.ts index 4ccf1157b..ad04d93ed 100644 --- a/ide/src/trace/component/trace/base/TraceSheet.ts +++ b/ide/src/trace/component/trace/base/TraceSheet.ts @@ -13,74 +13,74 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; -import { type LitTabs } from '../../../../base-ui/tabs/lit-tabs.js'; -import { LitTabpane } from '../../../../base-ui/tabs/lit-tabpane.js'; -import { BoxJumpParam, SelectionParam } from '../../../bean/BoxSelection.js'; -import { type TabPaneCurrentSelection } from '../sheet/TabPaneCurrentSelection.js'; -import { type TabPaneFlag } from '../timer-shaft/TabPaneFlag.js'; -import { type Flag } from '../timer-shaft/Flag.js'; -import { type WakeupBean } from '../../../bean/WakeupBean.js'; -import { type LitIcon } from '../../../../base-ui/icon/LitIcon.js'; -import { tabConfig } from './TraceSheetConfig.js'; -import { type TabPaneBoxChild } from '../sheet/cpu/TabPaneBoxChild.js'; -import { type CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU.js'; -import { CpuFreqStruct } from '../../../database/ui-worker/ProcedureWorkerFreq.js'; -import { CpuFreqLimitsStruct } from '../../../database/ui-worker/ProcedureWorkerCpuFreqLimits.js'; -import { type ThreadStruct } from '../../../database/ui-worker/ProcedureWorkerThread.js'; -import { type FuncStruct } from '../../../database/ui-worker/ProcedureWorkerFunc.js'; -import { ProcessMemStruct } from '../../../database/ui-worker/ProcedureWorkerMem.js'; -import { CpuStateStruct } from '../../../database/ui-worker/ProcedureWorkerCpuState.js'; -import { type ClockStruct } from '../../../database/ui-worker/ProcedureWorkerClock.js'; -import { type IrqStruct } from '../../../database/ui-worker/ProcedureWorkerIrq.js'; -import { type JankStruct } from '../../../database/ui-worker/ProcedureWorkerJank.js'; -import { type HeapStruct } from '../../../database/ui-worker/ProcedureWorkerHeap.js'; -import { type LitTable } from '../../../../base-ui/table/lit-table.js'; -import { threadPool } from '../../../database/SqlLite.js'; -import { type HeapSnapshotStruct } from '../../../database/ui-worker/ProcedureWorkerHeapSnapshot.js'; -import { type TabPaneNMStatisticAnalysis } from '../sheet/native-memory/TabPaneNMStatisticAnalysis.js'; -import { type TabPaneCurrent } from '../sheet/TabPaneCurrent.js'; -import { type SlicesTime } from '../timer-shaft/SportRuler.js'; -import { type AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAppStartup.js'; -import { type SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit.js'; -import { type FrameAnimationStruct } from '../../../database/ui-worker/ProcedureWorkerFrameAnimation.js'; -import { type TraceRow } from './TraceRow.js'; -import { type FrameDynamicStruct } from '../../../database/ui-worker/ProcedureWorkerFrameDynamic.js'; -import { type TabPaneFrameDynamic } from '../sheet/frame/TabPaneFrameDynamic.js'; -import { type FrameSpacingStruct } from '../../../database/ui-worker/ProcedureWorkerFrameSpacing.js'; -import { type TabFrameSpacing } from '../sheet/frame/TabFrameSpacing.js'; -import { type JsCpuProfilerChartFrame } from '../../../bean/JsStruct.js'; -import { type TabPaneComparison } from '../sheet/ark-ts/TabPaneComparison.js'; -import { type TabPaneSummary } from '../sheet/ark-ts/TabPaneSummary.js'; -import { type TabPaneGpuClickSelect } from '../sheet/gpu/TabPaneGpuClickSelect.js'; -import { type TabPanePurgTotalSelection } from '../sheet/ability/TabPanePurgTotalSelection.js'; -import { type TabPanePurgPinSelection } from '../sheet/ability/TabPanePurgPinSelection.js'; -import { type TabPaneVmTrackerShmSelection } from '../sheet/vmtracker/TabPaneVmTrackerShmSelection.js'; -import { type TabPaneSmapsStatistics } from '../sheet/smaps/TabPaneSmapsStatistics.js'; -import { type TabPaneSmapsComparison } from '../sheet/smaps/TabPaneSmapsComparison.js'; -import { type SnapshotStruct } from '../../../database/ui-worker/ProcedureWorkerSnapshot.js'; -import { type TabPaneDmaSelectAbility } from '../sheet/ability/TabPaneDmaSelectAbility.js'; -import { type TabPaneGpuMemorySelectAbility } from '../sheet/ability/TabPaneGpuMemorySelectAbility.js'; -import { type TabPaneDmaSelectVmTracker } from '../sheet/vmtracker/TabPaneDmaSelectVmTracker.js'; -import { type TabPanePurgTotalComparisonAbility } from '../sheet/ability/TabPanePurgTotalComparisonAbility.js'; -import { type TabPanePurgPinComparisonAbility } from '../sheet/ability/TabPanePurgPinComparisonAbility.js'; -import { type TabPanePurgTotalComparisonVM } from '../sheet/vmtracker/TabPanePurgTotalComparisonVM.js'; -import { type TabPanePurgPinComparisonVM } from '../sheet/vmtracker/TabPanePurgPinComparisonVM.js'; -import { type TabPaneDmaAbilityComparison } from '../sheet/ability/TabPaneDmaAbilityComparison.js'; -import { type TabPaneGpuMemoryComparison } from '../sheet/ability/TabPaneGpuMemoryComparison.js'; -import { type TabPaneDmaVmTrackerComparison } from '../sheet/vmtracker/TabPaneDmaVmTrackerComparison.js'; -import { type TabPaneGpuMemorySelectVmTracker } from '../sheet/vmtracker/TabPaneGpuMemorySelectVmTracker.js'; -import { type TabPaneGpuMemoryVmTrackerComparison } from '../sheet/vmtracker/TabPaneGpuMemoryVmTrackerComparison.js'; -import { type TabPaneVmTrackerShmComparison } from '../sheet/vmtracker/TabPaneVmTrackerShmComparison.js'; -import { type TabPaneJsCpuStatistics } from '../sheet/ark-ts/TabPaneJsCpuStatistics.js'; -import { type TabPaneGpuClickSelectComparison } from '../sheet/gpu/TabPaneGpuClickSelectComparison.js'; -import { Utils } from './Utils.js'; -import { TabPaneHiLogs } from '../sheet/hilog/TabPaneHiLogs.js'; -import { TabPaneGpuResourceVmTracker } from '../sheet/vmtracker/TabPaneGpuResourceVmTracker.js'; -import { type LitPageTable } from '../../../../base-ui/table/LitPageTable.js'; -import '../../../../base-ui/popover/LitPopoverV.js'; -import { LitPopover } from '../../../../base-ui/popover/LitPopoverV.js'; -import { LitTree, TreeItemData } from '../../../../base-ui/tree/LitTree.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; +import { type LitTabs } from '../../../../base-ui/tabs/lit-tabs'; +import { LitTabpane } from '../../../../base-ui/tabs/lit-tabpane'; +import { BoxJumpParam, SelectionParam } from '../../../bean/BoxSelection'; +import { type TabPaneCurrentSelection } from '../sheet/TabPaneCurrentSelection'; +import { type TabPaneFlag } from '../timer-shaft/TabPaneFlag'; +import { type Flag } from '../timer-shaft/Flag'; +import { type WakeupBean } from '../../../bean/WakeupBean'; +import { type LitIcon } from '../../../../base-ui/icon/LitIcon'; +import { tabConfig } from './TraceSheetConfig'; +import { type TabPaneBoxChild } from '../sheet/cpu/TabPaneBoxChild'; +import { type CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU'; +import { CpuFreqStruct } from '../../../database/ui-worker/ProcedureWorkerFreq'; +import { CpuFreqLimitsStruct } from '../../../database/ui-worker/ProcedureWorkerCpuFreqLimits'; +import { type ThreadStruct } from '../../../database/ui-worker/ProcedureWorkerThread'; +import { type FuncStruct } from '../../../database/ui-worker/ProcedureWorkerFunc'; +import { ProcessMemStruct } from '../../../database/ui-worker/ProcedureWorkerMem'; +import { CpuStateStruct } from '../../../database/ui-worker/ProcedureWorkerCpuState'; +import { type ClockStruct } from '../../../database/ui-worker/ProcedureWorkerClock'; +import { type IrqStruct } from '../../../database/ui-worker/ProcedureWorkerIrq'; +import { type JankStruct } from '../../../database/ui-worker/ProcedureWorkerJank'; +import { type HeapStruct } from '../../../database/ui-worker/ProcedureWorkerHeap'; +import { type LitTable } from '../../../../base-ui/table/lit-table'; +import { threadPool } from '../../../database/SqlLite'; +import { type HeapSnapshotStruct } from '../../../database/ui-worker/ProcedureWorkerHeapSnapshot'; +import { type TabPaneNMStatisticAnalysis } from '../sheet/native-memory/TabPaneNMStatisticAnalysis'; +import { type TabPaneCurrent } from '../sheet/TabPaneCurrent'; +import { type SlicesTime } from '../timer-shaft/SportRuler'; +import { type AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAppStartup'; +import { type SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit'; +import { type FrameAnimationStruct } from '../../../database/ui-worker/ProcedureWorkerFrameAnimation'; +import { type TraceRow } from './TraceRow'; +import { type FrameDynamicStruct } from '../../../database/ui-worker/ProcedureWorkerFrameDynamic'; +import { type TabPaneFrameDynamic } from '../sheet/frame/TabPaneFrameDynamic'; +import { type FrameSpacingStruct } from '../../../database/ui-worker/ProcedureWorkerFrameSpacing'; +import { type TabFrameSpacing } from '../sheet/frame/TabFrameSpacing'; +import { type JsCpuProfilerChartFrame } from '../../../bean/JsStruct'; +import { type TabPaneComparison } from '../sheet/ark-ts/TabPaneComparison'; +import { type TabPaneSummary } from '../sheet/ark-ts/TabPaneSummary'; +import { type TabPaneGpuClickSelect } from '../sheet/gpu/TabPaneGpuClickSelect'; +import { type TabPanePurgTotalSelection } from '../sheet/ability/TabPanePurgTotalSelection'; +import { type TabPanePurgPinSelection } from '../sheet/ability/TabPanePurgPinSelection'; +import { type TabPaneVmTrackerShmSelection } from '../sheet/vmtracker/TabPaneVmTrackerShmSelection'; +import { type TabPaneSmapsStatistics } from '../sheet/smaps/TabPaneSmapsStatistics'; +import { type TabPaneSmapsComparison } from '../sheet/smaps/TabPaneSmapsComparison'; +import { type SnapshotStruct } from '../../../database/ui-worker/ProcedureWorkerSnapshot'; +import { type TabPaneDmaSelectAbility } from '../sheet/ability/TabPaneDmaSelectAbility'; +import { type TabPaneGpuMemorySelectAbility } from '../sheet/ability/TabPaneGpuMemorySelectAbility'; +import { type TabPaneDmaSelectVmTracker } from '../sheet/vmtracker/TabPaneDmaSelectVmTracker'; +import { type TabPanePurgTotalComparisonAbility } from '../sheet/ability/TabPanePurgTotalComparisonAbility'; +import { type TabPanePurgPinComparisonAbility } from '../sheet/ability/TabPanePurgPinComparisonAbility'; +import { type TabPanePurgTotalComparisonVM } from '../sheet/vmtracker/TabPanePurgTotalComparisonVM'; +import { type TabPanePurgPinComparisonVM } from '../sheet/vmtracker/TabPanePurgPinComparisonVM'; +import { type TabPaneDmaAbilityComparison } from '../sheet/ability/TabPaneDmaAbilityComparison'; +import { type TabPaneGpuMemoryComparison } from '../sheet/ability/TabPaneGpuMemoryComparison'; +import { type TabPaneDmaVmTrackerComparison } from '../sheet/vmtracker/TabPaneDmaVmTrackerComparison'; +import { type TabPaneGpuMemorySelectVmTracker } from '../sheet/vmtracker/TabPaneGpuMemorySelectVmTracker'; +import { type TabPaneGpuMemoryVmTrackerComparison } from '../sheet/vmtracker/TabPaneGpuMemoryVmTrackerComparison'; +import { type TabPaneVmTrackerShmComparison } from '../sheet/vmtracker/TabPaneVmTrackerShmComparison'; +import { type TabPaneJsCpuStatistics } from '../sheet/ark-ts/TabPaneJsCpuStatistics'; +import { type TabPaneGpuClickSelectComparison } from '../sheet/gpu/TabPaneGpuClickSelectComparison'; +import { Utils } from './Utils'; +import { TabPaneHiLogs } from '../sheet/hilog/TabPaneHiLogs'; +import { TabPaneGpuResourceVmTracker } from '../sheet/vmtracker/TabPaneGpuResourceVmTracker'; +import { type LitPageTable } from '../../../../base-ui/table/LitPageTable'; +import '../../../../base-ui/popover/LitPopoverV'; +import { LitPopover } from '../../../../base-ui/popover/LitPopoverV'; +import { LitTree, TreeItemData } from '../../../../base-ui/tree/LitTree'; @element('trace-sheet') export class TraceSheet extends BaseElement { diff --git a/ide/src/trace/component/trace/base/TraceSheetConfig.ts b/ide/src/trace/component/trace/base/TraceSheetConfig.ts index ff0f3522d..52a5a2bec 100644 --- a/ide/src/trace/component/trace/base/TraceSheetConfig.ts +++ b/ide/src/trace/component/trace/base/TraceSheetConfig.ts @@ -13,115 +13,115 @@ * limitations under the License. */ -import { TabPaneCurrentSelection } from '../sheet/TabPaneCurrentSelection.js'; -import { TabPaneFreq } from '../sheet/freq/TabPaneFreq.js'; -import { TabPaneCpuByThread } from '../sheet/cpu/TabPaneCpuByThread.js'; -import { SelectionParam } from '../../../bean/BoxSelection.js'; -import { TabPaneCpuByProcess } from '../sheet/cpu/TabPaneCpuByProcess.js'; -import { TabPaneCpuUsage } from '../sheet/cpu/TabPaneCpuUsage.js'; -import { TabPaneSPT } from '../sheet/cpu/TabPaneSPT.js'; -import { TabPanePTS } from '../sheet/cpu/TabPanePTS.js'; -import { TabPaneSlices } from '../sheet/process/TabPaneSlices.js'; -import { TabPaneCounter } from '../sheet/process/TabPaneCounter.js'; -import { TabPaneFps } from '../sheet/fps/TabPaneFps.js'; -import { TabPaneFlag } from '../timer-shaft/TabPaneFlag.js'; -import { TabPaneBoxChild } from '../sheet/cpu/TabPaneBoxChild.js'; -import { TabPaneNMStatstics } from '../sheet/native-memory/TabPaneNMStatstics.js'; -import { TabPaneNMemory } from '../sheet/native-memory/TabPaneNMemory.js'; -import { TabPaneNMSampleList } from '../sheet/native-memory/TabPaneNMSampleList.js'; -import { TabpanePerfProfile } from '../sheet/hiperf/TabPerfProfile.js'; -import { TabPanePerfSample } from '../sheet/hiperf/TabPerfSampleList.js'; -import { TabPaneLiveProcesses } from '../sheet/ability/TabPaneLiveProcesses.js'; -import { TabPaneHistoryProcesses } from '../sheet/ability/TabPaneHistoryProcesses.js'; -import { TabPaneCpuAbility } from '../sheet/ability/TabPaneCpuAbility.js'; -import { TabPaneMemoryAbility } from '../sheet/ability/TabPaneMemoryAbility.js'; -import { TabPaneDiskAbility } from '../sheet/ability/TabPaneDiskAbility.js'; -import { TabPaneNetworkAbility } from '../sheet/ability/TabPaneNetworkAbility.js'; -import { TabPaneFileStatistics } from '../sheet/file-system/TabPaneFilesystemStatistics.js'; -import { TabpaneFilesystemCalltree } from '../sheet/file-system/TabPaneFileSystemCalltree.js'; -import { TabPaneFileSystemEvents } from '../sheet/file-system/TabPaneFileSystemEvents.js'; -import { TabPaneFileSystemDescHistory } from '../sheet/file-system/TabPaneFileSystemDescHistory.js'; -import { TabPaneFileSystemDescTimeSlice } from '../sheet/file-system/TabPaneFileSystemDescTimeSlice.js'; -import { TabPaneSdkSlice } from '../sheet/sdk/TabPaneSdkSlice.js'; -import { TabPaneSdkCounter } from '../sheet/sdk/TabPaneSdkCounter.js'; -import { TabPaneCounterSample } from '../sheet/cpu/TabPaneCounterSample.js'; -import { TabPaneThreadStates } from '../sheet/process/TabPaneThreadStates.js'; -import { TabPaneThreadUsage } from '../sheet/process/TabPaneThreadUsage.js'; -import { TabPaneFrequencySample } from '../sheet/cpu/TabPaneFrequencySample.js'; -import { TabPaneEnergyAnomaly } from '../sheet/energy/TabPaneEnergyAnomaly.js'; -import { TabPaneSystemDetails } from '../sheet/energy/TabPaneSystemDetails.js'; -import { TabPanePowerDetails } from '../sheet/energy/TabPanePowerDetails.js'; -import { TabPanePowerBattery } from '../sheet/energy/TabPanePowerBattery.js'; -import { TabPaneCpuStateClick } from '../sheet/cpu/TabPaneCpuStateClick.js'; -import { TabPaneVirtualMemoryStatistics } from '../sheet/file-system/TabPaneVirtualMemoryStatistics.js'; -import { TabPaneIOTierStatistics } from '../sheet/file-system/TabPaneIOTierStatistics.js'; -import { TabPaneIOCallTree, TabPaneVMCallTree } from '../sheet/file-system/TabPaneIOCallTree.js'; -import { TabPaneIoCompletionTimes } from '../sheet/file-system/TabPaneIoCompletionTimes.js'; -import { TabPaneVirtualMemoryEvents } from '../sheet/file-system/TabPaneVMEvents.js'; -import { TabPaneSmapsStatistics } from '../sheet/smaps/TabPaneSmapsStatistics.js'; -import { TabPaneSmapsSample } from '../sheet/smaps/TabPaneSmapsSample.js'; -import { TabPaneFreqLimit } from '../sheet/freq/TabPaneFreqLimit.js'; -import { TabPaneCpuFreqLimits } from '../sheet/freq/TabPaneCpuFreqLimits.js'; -import { TabpaneNMCalltree } from '../sheet/native-memory/TabPaneNMCallTree.js'; -import { TabPaneClockCounter } from '../sheet/clock/TabPaneClockCounter.js'; -import { TabPaneIrqCounter } from '../sheet/irq/TabPaneIrqCounter.js'; -import { TabPaneFrames } from '../sheet/jank/TabPaneFrames.js'; -import { TabPanePerfAnalysis } from '../sheet/hiperf/TabPanePerfAnalysis.js'; -import { TabPaneNMStatisticAnalysis } from '../sheet/native-memory/TabPaneNMStatisticAnalysis.js'; -import { TabPaneFilesystemStatisticsAnalysis } from '../sheet/file-system/TabPaneFilesystemStatisticsAnalysis.js'; -import { TabPaneIOTierStatisticsAnalysis } from '../sheet/file-system/TabPaneIOTierStatisticsAnalysis.js'; -import { TabPaneVirtualMemoryStatisticsAnalysis } from '../sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.js'; -import { TabPaneCurrent } from '../sheet/TabPaneCurrent.js'; -import { TabPaneStartup } from '../sheet/process/TabPaneStartup.js'; -import { TabPaneStaticInit } from '../sheet/process/TabPaneStaticInit.js'; -import { TabPaneTaskFrames } from '../sheet/task/TabPaneTaskFrames.js'; -import { TabPaneFrameDynamic } from '../sheet/frame/TabPaneFrameDynamic.js'; -import { TabFrameSpacing } from '../sheet/frame/TabFrameSpacing.js'; -import { TabPaneSummary } from '../sheet/ark-ts/TabPaneSummary.js'; -import { TabPaneComparison } from '../sheet/ark-ts/TabPaneComparison.js'; -import { TabPaneJsCpuTopDown } from '../sheet/ark-ts/TabPaneJsCpuCallTree.js'; -import { TabPaneJsCpuBottomUp } from '../sheet/ark-ts/TabPaneJsCpuBottomUp.js'; -import { TabPaneJsCpuStatistics } from '../sheet/ark-ts/TabPaneJsCpuStatistics.js'; -import { TabPaneGpuClickSelect } from '../sheet/gpu/TabPaneGpuClickSelect.js'; -import { TabPaneGpuTotalBoxSelect } from '../sheet/gpu/TabPaneGpuTotalBoxSelect.js'; -import { TabPaneGpuWindowBoxSelect } from '../sheet/gpu/TabPaneGpuWindowBoxSelect.js'; -import { TabPaneGpuGL } from '../sheet/gpu/TabPaneGpuGL.js'; -import { TabPanePurgTotal } from '../sheet/ability/TabPanePurgTotal.js'; -import { TabPanePurgTotalSelection } from '../sheet/ability/TabPanePurgTotalSelection.js'; -import { TabPanePurgPin } from '../sheet/ability/TabPanePurgPin.js'; -import { TabPanePurgPinSelection } from '../sheet/ability/TabPanePurgPinSelection.js'; -import { TabPaneVmTrackerShmSelection } from '../sheet/vmtracker/TabPaneVmTrackerShmSelection.js'; -import { TabPaneVmTrackerShm } from '../sheet/vmtracker/TabPaneVmTrackerShm.js'; -import { TabPaneDmaAbility } from '../sheet/ability/TabPaneDmaAbility.js'; -import { TabPaneDmaSelectAbility } from '../sheet/ability/TabPaneDmaSelectAbility.js'; -import { TabPaneGpuMemoryAbility } from '../sheet/ability/TabPaneGpuMemoryAbility.js'; -import { TabPaneDmaVmTracker } from '../sheet/vmtracker/TabPaneDmaVmTracker.js'; -import { TabPaneGpuMemoryVmTracker } from '../sheet/vmtracker/TabPaneGpuMemoryVmTracker.js'; -import { TabPaneGpuMemorySelectAbility } from '../sheet/ability/TabPaneGpuMemorySelectAbility.js'; -import { TabPaneGpuMemorySelectVmTracker } from '../sheet/vmtracker/TabPaneGpuMemorySelectVmTracker.js'; -import { TabPaneDmaSelectVmTracker } from '../sheet/vmtracker/TabPaneDmaSelectVmTracker.js'; -import { TabpanePerfBottomUp } from '../sheet/hiperf/TabPerfBottomUp.js'; -import { TabPanePurgTotalComparisonAbility } from '../sheet/ability/TabPanePurgTotalComparisonAbility.js'; -import { TabPanePurgPinComparisonAbility } from '../sheet/ability/TabPanePurgPinComparisonAbility.js'; -import { TabPanePurgTotalComparisonVM } from '../sheet/vmtracker/TabPanePurgTotalComparisonVM.js'; -import { TabPanePurgPinComparisonVM } from '../sheet/vmtracker/TabPanePurgPinComparisonVM.js'; -import { TabPaneDmaAbilityComparison } from '../sheet/ability/TabPaneDmaAbilityComparison.js'; -import { TabPaneGpuMemoryComparison } from '../sheet/ability/TabPaneGpuMemoryComparison.js'; -import { TabPaneDmaVmTrackerComparison } from '../sheet/vmtracker/TabPaneDmaVmTrackerComparison.js'; -import { TabPaneGpuMemoryVmTrackerComparison } from '../sheet/vmtracker/TabPaneGpuMemoryVmTrackerComparison.js'; -import { TabPaneVmTrackerShmComparison } from '../sheet/vmtracker/TabPaneVmTrackerShmComparison.js'; -import { TabPaneSmapsComparison } from '../sheet/smaps/TabPaneSmapsComparison.js'; -import { TabPaneSmapsRecord } from '../sheet/smaps/TabPaneSmapsRecord.js'; -import { TabPaneGpuClickSelectComparison } from '../sheet/gpu/TabPaneGpuClickSelectComparison.js'; -import { TabPaneHiLogs } from '../sheet/hilog/TabPaneHiLogs.js'; -import { TabPaneHiLogSummary } from '../sheet/hilog/TabPaneHiLogSummary.js'; -import { TabPaneSchedPriority } from '../sheet/cpu/TabPaneSchedPriority.js'; -import { TabPaneGpuResourceVmTracker } from '../sheet/vmtracker/TabPaneGpuResourceVmTracker.js'; -import { TabPaneGpuGraph } from '../sheet/gpu/TabPaneGraph.js'; -import { TabPaneFreqUsage } from '../sheet/frequsage/TabPaneFreqUsage.js'; -import { TabPaneFreqDataCut } from '../sheet/frequsage/TabPaneFreqDataCut.js'; -import { TabPaneHisysEvents } from '../sheet/hisysevent/TabPaneHisysEvents.js'; -import { TabPaneHiSysEventSummary } from '../sheet/hisysevent/TabPaneHiSysEventSummary.js'; +import { TabPaneCurrentSelection } from '../sheet/TabPaneCurrentSelection'; +import { TabPaneFreq } from '../sheet/freq/TabPaneFreq'; +import { TabPaneCpuByThread } from '../sheet/cpu/TabPaneCpuByThread'; +import { SelectionParam } from '../../../bean/BoxSelection'; +import { TabPaneCpuByProcess } from '../sheet/cpu/TabPaneCpuByProcess'; +import { TabPaneCpuUsage } from '../sheet/cpu/TabPaneCpuUsage'; +import { TabPaneSPT } from '../sheet/cpu/TabPaneSPT'; +import { TabPanePTS } from '../sheet/cpu/TabPanePTS'; +import { TabPaneSlices } from '../sheet/process/TabPaneSlices'; +import { TabPaneCounter } from '../sheet/process/TabPaneCounter'; +import { TabPaneFps } from '../sheet/fps/TabPaneFps'; +import { TabPaneFlag } from '../timer-shaft/TabPaneFlag'; +import { TabPaneBoxChild } from '../sheet/cpu/TabPaneBoxChild'; +import { TabPaneNMStatstics } from '../sheet/native-memory/TabPaneNMStatstics'; +import { TabPaneNMemory } from '../sheet/native-memory/TabPaneNMemory'; +import { TabPaneNMSampleList } from '../sheet/native-memory/TabPaneNMSampleList'; +import { TabpanePerfProfile } from '../sheet/hiperf/TabPerfProfile'; +import { TabPanePerfSample } from '../sheet/hiperf/TabPerfSampleList'; +import { TabPaneLiveProcesses } from '../sheet/ability/TabPaneLiveProcesses'; +import { TabPaneHistoryProcesses } from '../sheet/ability/TabPaneHistoryProcesses'; +import { TabPaneCpuAbility } from '../sheet/ability/TabPaneCpuAbility'; +import { TabPaneMemoryAbility } from '../sheet/ability/TabPaneMemoryAbility'; +import { TabPaneDiskAbility } from '../sheet/ability/TabPaneDiskAbility'; +import { TabPaneNetworkAbility } from '../sheet/ability/TabPaneNetworkAbility'; +import { TabPaneFileStatistics } from '../sheet/file-system/TabPaneFilesystemStatistics'; +import { TabpaneFilesystemCalltree } from '../sheet/file-system/TabPaneFileSystemCalltree'; +import { TabPaneFileSystemEvents } from '../sheet/file-system/TabPaneFileSystemEvents'; +import { TabPaneFileSystemDescHistory } from '../sheet/file-system/TabPaneFileSystemDescHistory'; +import { TabPaneFileSystemDescTimeSlice } from '../sheet/file-system/TabPaneFileSystemDescTimeSlice'; +import { TabPaneSdkSlice } from '../sheet/sdk/TabPaneSdkSlice'; +import { TabPaneSdkCounter } from '../sheet/sdk/TabPaneSdkCounter'; +import { TabPaneCounterSample } from '../sheet/cpu/TabPaneCounterSample'; +import { TabPaneThreadStates } from '../sheet/process/TabPaneThreadStates'; +import { TabPaneThreadUsage } from '../sheet/process/TabPaneThreadUsage'; +import { TabPaneFrequencySample } from '../sheet/cpu/TabPaneFrequencySample'; +import { TabPaneEnergyAnomaly } from '../sheet/energy/TabPaneEnergyAnomaly'; +import { TabPaneSystemDetails } from '../sheet/energy/TabPaneSystemDetails'; +import { TabPanePowerDetails } from '../sheet/energy/TabPanePowerDetails'; +import { TabPanePowerBattery } from '../sheet/energy/TabPanePowerBattery'; +import { TabPaneCpuStateClick } from '../sheet/cpu/TabPaneCpuStateClick'; +import { TabPaneVirtualMemoryStatistics } from '../sheet/file-system/TabPaneVirtualMemoryStatistics'; +import { TabPaneIOTierStatistics } from '../sheet/file-system/TabPaneIOTierStatistics'; +import { TabPaneIOCallTree, TabPaneVMCallTree } from '../sheet/file-system/TabPaneIOCallTree'; +import { TabPaneIoCompletionTimes } from '../sheet/file-system/TabPaneIoCompletionTimes'; +import { TabPaneVirtualMemoryEvents } from '../sheet/file-system/TabPaneVMEvents'; +import { TabPaneSmapsStatistics } from '../sheet/smaps/TabPaneSmapsStatistics'; +import { TabPaneSmapsSample } from '../sheet/smaps/TabPaneSmapsSample'; +import { TabPaneFreqLimit } from '../sheet/freq/TabPaneFreqLimit'; +import { TabPaneCpuFreqLimits } from '../sheet/freq/TabPaneCpuFreqLimits'; +import { TabpaneNMCalltree } from '../sheet/native-memory/TabPaneNMCallTree'; +import { TabPaneClockCounter } from '../sheet/clock/TabPaneClockCounter'; +import { TabPaneIrqCounter } from '../sheet/irq/TabPaneIrqCounter'; +import { TabPaneFrames } from '../sheet/jank/TabPaneFrames'; +import { TabPanePerfAnalysis } from '../sheet/hiperf/TabPanePerfAnalysis'; +import { TabPaneNMStatisticAnalysis } from '../sheet/native-memory/TabPaneNMStatisticAnalysis'; +import { TabPaneFilesystemStatisticsAnalysis } from '../sheet/file-system/TabPaneFilesystemStatisticsAnalysis'; +import { TabPaneIOTierStatisticsAnalysis } from '../sheet/file-system/TabPaneIOTierStatisticsAnalysis'; +import { TabPaneVirtualMemoryStatisticsAnalysis } from '../sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis'; +import { TabPaneCurrent } from '../sheet/TabPaneCurrent'; +import { TabPaneStartup } from '../sheet/process/TabPaneStartup'; +import { TabPaneStaticInit } from '../sheet/process/TabPaneStaticInit'; +import { TabPaneTaskFrames } from '../sheet/task/TabPaneTaskFrames'; +import { TabPaneFrameDynamic } from '../sheet/frame/TabPaneFrameDynamic'; +import { TabFrameSpacing } from '../sheet/frame/TabFrameSpacing'; +import { TabPaneSummary } from '../sheet/ark-ts/TabPaneSummary'; +import { TabPaneComparison } from '../sheet/ark-ts/TabPaneComparison'; +import { TabPaneJsCpuTopDown } from '../sheet/ark-ts/TabPaneJsCpuCallTree'; +import { TabPaneJsCpuBottomUp } from '../sheet/ark-ts/TabPaneJsCpuBottomUp'; +import { TabPaneJsCpuStatistics } from '../sheet/ark-ts/TabPaneJsCpuStatistics'; +import { TabPaneGpuClickSelect } from '../sheet/gpu/TabPaneGpuClickSelect'; +import { TabPaneGpuTotalBoxSelect } from '../sheet/gpu/TabPaneGpuTotalBoxSelect'; +import { TabPaneGpuWindowBoxSelect } from '../sheet/gpu/TabPaneGpuWindowBoxSelect'; +import { TabPaneGpuGL } from '../sheet/gpu/TabPaneGpuGL'; +import { TabPanePurgTotal } from '../sheet/ability/TabPanePurgTotal'; +import { TabPanePurgTotalSelection } from '../sheet/ability/TabPanePurgTotalSelection'; +import { TabPanePurgPin } from '../sheet/ability/TabPanePurgPin'; +import { TabPanePurgPinSelection } from '../sheet/ability/TabPanePurgPinSelection'; +import { TabPaneVmTrackerShmSelection } from '../sheet/vmtracker/TabPaneVmTrackerShmSelection'; +import { TabPaneVmTrackerShm } from '../sheet/vmtracker/TabPaneVmTrackerShm'; +import { TabPaneDmaAbility } from '../sheet/ability/TabPaneDmaAbility'; +import { TabPaneDmaSelectAbility } from '../sheet/ability/TabPaneDmaSelectAbility'; +import { TabPaneGpuMemoryAbility } from '../sheet/ability/TabPaneGpuMemoryAbility'; +import { TabPaneDmaVmTracker } from '../sheet/vmtracker/TabPaneDmaVmTracker'; +import { TabPaneGpuMemoryVmTracker } from '../sheet/vmtracker/TabPaneGpuMemoryVmTracker'; +import { TabPaneGpuMemorySelectAbility } from '../sheet/ability/TabPaneGpuMemorySelectAbility'; +import { TabPaneGpuMemorySelectVmTracker } from '../sheet/vmtracker/TabPaneGpuMemorySelectVmTracker'; +import { TabPaneDmaSelectVmTracker } from '../sheet/vmtracker/TabPaneDmaSelectVmTracker'; +import { TabpanePerfBottomUp } from '../sheet/hiperf/TabPerfBottomUp'; +import { TabPanePurgTotalComparisonAbility } from '../sheet/ability/TabPanePurgTotalComparisonAbility'; +import { TabPanePurgPinComparisonAbility } from '../sheet/ability/TabPanePurgPinComparisonAbility'; +import { TabPanePurgTotalComparisonVM } from '../sheet/vmtracker/TabPanePurgTotalComparisonVM'; +import { TabPanePurgPinComparisonVM } from '../sheet/vmtracker/TabPanePurgPinComparisonVM'; +import { TabPaneDmaAbilityComparison } from '../sheet/ability/TabPaneDmaAbilityComparison'; +import { TabPaneGpuMemoryComparison } from '../sheet/ability/TabPaneGpuMemoryComparison'; +import { TabPaneDmaVmTrackerComparison } from '../sheet/vmtracker/TabPaneDmaVmTrackerComparison'; +import { TabPaneGpuMemoryVmTrackerComparison } from '../sheet/vmtracker/TabPaneGpuMemoryVmTrackerComparison'; +import { TabPaneVmTrackerShmComparison } from '../sheet/vmtracker/TabPaneVmTrackerShmComparison'; +import { TabPaneSmapsComparison } from '../sheet/smaps/TabPaneSmapsComparison'; +import { TabPaneSmapsRecord } from '../sheet/smaps/TabPaneSmapsRecord'; +import { TabPaneGpuClickSelectComparison } from '../sheet/gpu/TabPaneGpuClickSelectComparison'; +import { TabPaneHiLogs } from '../sheet/hilog/TabPaneHiLogs'; +import { TabPaneHiLogSummary } from '../sheet/hilog/TabPaneHiLogSummary'; +import { TabPaneSchedPriority } from '../sheet/cpu/TabPaneSchedPriority'; +import { TabPaneGpuResourceVmTracker } from '../sheet/vmtracker/TabPaneGpuResourceVmTracker'; +import { TabPaneGpuGraph } from '../sheet/gpu/TabPaneGraph'; +import { TabPaneFreqUsage } from '../sheet/frequsage/TabPaneFreqUsage'; +import { TabPaneFreqDataCut } from '../sheet/frequsage/TabPaneFreqDataCut'; +import { TabPaneHisysEvents } from '../sheet/hisysevent/TabPaneHisysEvents'; +import { TabPaneHiSysEventSummary } from '../sheet/hisysevent/TabPaneHiSysEventSummary'; export let tabConfig: any = { 'current-selection': { diff --git a/ide/src/trace/component/trace/base/Utils.ts b/ide/src/trace/component/trace/base/Utils.ts index 12cbe7751..dac79637c 100644 --- a/ide/src/trace/component/trace/base/Utils.ts +++ b/ide/src/trace/component/trace/base/Utils.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { SelectionParam } from '../../../bean/BoxSelection.js'; -import { procedurePool } from '../../../database/Procedure.js'; -import { queryNativeHookResponseTypes } from '../../../database/SqlLite.js'; +import { SelectionParam } from '../../../bean/BoxSelection'; +import { procedurePool } from '../../../database/Procedure'; +import { queryNativeHookResponseTypes } from '../../../database/SqlLite'; export class Utils { private static statusMap: Map = new Map(); diff --git a/ide/src/trace/component/trace/search/Search.ts b/ide/src/trace/component/trace/search/Search.ts index 343333236..18696bdc5 100644 --- a/ide/src/trace/component/trace/search/Search.ts +++ b/ide/src/trace/component/trace/search/Search.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; -import { LitIcon } from '../../../../base-ui/icon/LitIcon.js'; -import { SpSystemTrace } from '../../../component/SpSystemTrace.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; +import { LitIcon } from '../../../../base-ui/icon/LitIcon'; +import { SpSystemTrace } from '../../../component/SpSystemTrace'; const LOCAL_STORAGE_SEARCH_KEY = 'search_key'; diff --git a/ide/src/trace/component/trace/sheet/SheetUtils.ts b/ide/src/trace/component/trace/sheet/SheetUtils.ts index 9635f1965..b0c8b1280 100644 --- a/ide/src/trace/component/trace/sheet/SheetUtils.ts +++ b/ide/src/trace/component/trace/sheet/SheetUtils.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { LitTable } from '../../../../base-ui/table/lit-table.js'; -import { NativeMemoryExpression } from '../../../bean/NativeHook.js'; +import { LitTable } from '../../../../base-ui/table/lit-table'; +import { NativeMemoryExpression } from '../../../bean/NativeHook'; export function resizeObserver( parentEl: HTMLElement, diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts index cb064fd5c..97530e60f 100644 --- a/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts +++ b/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../base-ui/table/lit-table.js'; -import { MarkStruct } from '../../../bean/MarkStruct.js'; -import { SpSystemTrace } from '../../SpSystemTrace.js'; -import { ns2s } from '../TimerShaftElement.js'; -import { SlicesTime, StType } from '../timer-shaft/SportRuler.js'; -import { getTimeString } from './TabPaneCurrentSelection.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../base-ui/table/lit-table'; +import { MarkStruct } from '../../../bean/MarkStruct'; +import { SpSystemTrace } from '../../SpSystemTrace'; +import { ns2s } from '../TimerShaftElement'; +import { SlicesTime, StType } from '../timer-shaft/SportRuler'; +import { getTimeString } from './TabPaneCurrentSelection'; @element('tabpane-current') export class TabPaneCurrent extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts index f57ea33ea..cf09f48f4 100644 --- a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts +++ b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../base-ui/table/lit-table.js'; -import '../../../../base-ui/table/lit-table-column.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../base-ui/table/lit-table'; +import '../../../../base-ui/table/lit-table-column'; import { queryBinderArgsByArgset, @@ -30,25 +30,25 @@ import { queryThreadWakeUp, queryThreadWakeUpFrom, queryWakeupListPriority, -} from '../../../database/SqlLite.js'; -import { type WakeupBean } from '../../../bean/WakeupBean.js'; -import { SpApplication } from '../../../SpApplication.js'; -import { TraceRow } from '../base/TraceRow.js'; -import { CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU.js'; -import { ThreadStruct } from '../../../database/ui-worker/ProcedureWorkerThread.js'; -import { FuncStruct } from '../../../database/ui-worker/ProcedureWorkerFunc.js'; -import { ProcessMemStruct } from '../../../database/ui-worker/ProcedureWorkerMem.js'; -import { ClockStruct } from '../../../database/ui-worker/ProcedureWorkerClock.js'; -import { ColorUtils } from '../base/ColorUtils.js'; -import { IrqStruct } from '../../../database/ui-worker/ProcedureWorkerIrq.js'; -import { BinderArgBean } from '../../../bean/BinderArgBean.js'; -import { JankStruct } from '../../../database/ui-worker/ProcedureWorkerJank.js'; -import { Utils } from '../base/Utils.js'; -import { SpSystemTrace } from '../../SpSystemTrace.js'; -import { AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAppStartup.js'; -import { SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit.js'; -import { type SelectionParam } from '../../../bean/BoxSelection.js'; -import { type FrameAnimationStruct } from '../../../database/ui-worker/ProcedureWorkerFrameAnimation.js'; +} from '../../../database/SqlLite'; +import { type WakeupBean } from '../../../bean/WakeupBean'; +import { SpApplication } from '../../../SpApplication'; +import { TraceRow } from '../base/TraceRow'; +import { CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU'; +import { ThreadStruct } from '../../../database/ui-worker/ProcedureWorkerThread'; +import { FuncStruct } from '../../../database/ui-worker/ProcedureWorkerFunc'; +import { ProcessMemStruct } from '../../../database/ui-worker/ProcedureWorkerMem'; +import { ClockStruct } from '../../../database/ui-worker/ProcedureWorkerClock'; +import { ColorUtils } from '../base/ColorUtils'; +import { IrqStruct } from '../../../database/ui-worker/ProcedureWorkerIrq'; +import { BinderArgBean } from '../../../bean/BinderArgBean'; +import { JankStruct } from '../../../database/ui-worker/ProcedureWorkerJank'; +import { Utils } from '../base/Utils'; +import { SpSystemTrace } from '../../SpSystemTrace'; +import { AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAppStartup'; +import { SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit'; +import { type SelectionParam } from '../../../bean/BoxSelection'; +import { type FrameAnimationStruct } from '../../../database/ui-worker/ProcedureWorkerFrameAnimation'; const INPUT_WORD = 'This is the interval from when the task became eligible to run \n(e.g.because of notifying a wait queue it was a suspended on) to\n when it started running.'; diff --git a/ide/src/trace/component/trace/sheet/TabPaneFilter.ts b/ide/src/trace/component/trace/sheet/TabPaneFilter.ts index 12a79097c..d1eb77c1b 100644 --- a/ide/src/trace/component/trace/sheet/TabPaneFilter.ts +++ b/ide/src/trace/component/trace/sheet/TabPaneFilter.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; -import '../../../../base-ui/select/LitSelect.js'; -import '../../../../base-ui/select/LitSelectOption.js'; -import '../../../../base-ui/icon/LitIcon.js'; -import { LitIcon } from '../../../../base-ui/icon/LitIcon.js'; -import '../../../../base-ui/popover/LitPopoverV.js'; -import { LitCheckBox } from '../../../../base-ui/checkbox/LitCheckBox.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; +import '../../../../base-ui/select/LitSelect'; +import '../../../../base-ui/select/LitSelectOption'; +import '../../../../base-ui/icon/LitIcon'; +import { LitIcon } from '../../../../base-ui/icon/LitIcon'; +import '../../../../base-ui/popover/LitPopoverV'; +import { LitCheckBox } from '../../../../base-ui/checkbox/LitCheckBox'; import { LitSelect } from '../../../../base-ui/select/LitSelect'; -import { queryTransferList } from '../../../database/SqlLite.js'; +import { queryTransferList } from '../../../database/SqlLite'; export interface FilterData { inputValue: string; diff --git a/ide/src/trace/component/trace/sheet/TabPaneJsMemoryFilter.ts b/ide/src/trace/component/trace/sheet/TabPaneJsMemoryFilter.ts index af6ab82d4..b0bb5ccfb 100644 --- a/ide/src/trace/component/trace/sheet/TabPaneJsMemoryFilter.ts +++ b/ide/src/trace/component/trace/sheet/TabPaneJsMemoryFilter.ts @@ -12,14 +12,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; -import '../../../../base-ui/icon/LitIcon.js'; -import { LitIcon } from '../../../../base-ui/icon/LitIcon.js'; -import '../../../../base-ui/popover/LitPopoverV.js'; -import { LitCheckBox } from '../../../../base-ui/checkbox/LitCheckBox.js'; -import { LitSelect } from '../../../../base-ui/select/LitSelect.js'; -import '../../../../base-ui/select/LitSelect.js'; -import { LitSelectOption } from '../../../../base-ui/select/LitSelectOption.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; +import '../../../../base-ui/icon/LitIcon'; +import { LitIcon } from '../../../../base-ui/icon/LitIcon'; +import '../../../../base-ui/popover/LitPopoverV'; +import { LitCheckBox } from '../../../../base-ui/checkbox/LitCheckBox'; +import { LitSelect } from '../../../../base-ui/select/LitSelect'; +import '../../../../base-ui/select/LitSelect'; +import { LitSelectOption } from '../../../../base-ui/select/LitSelectOption'; @element('tab-pane-js-memory-filter') export class TabPaneJsMemoryFilter extends BaseElement { initElements(): void {} diff --git a/ide/src/trace/component/trace/sheet/TabProgressBar.ts b/ide/src/trace/component/trace/sheet/TabProgressBar.ts index 469e869aa..7e5bb8363 100644 --- a/ide/src/trace/component/trace/sheet/TabProgressBar.ts +++ b/ide/src/trace/component/trace/sheet/TabProgressBar.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; @element('tab-progress-bar') export class TabProgressBar extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneCpuAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneCpuAbility.ts index 8a4ef8392..be51b8887 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneCpuAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneCpuAbility.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabCpuAbilityData } from '../../../../database/SqlLite.js'; -import { SystemCpuSummary } from '../../../../bean/AbilityMonitor.js'; -import { Utils } from '../../base/Utils.js'; -import { ColorUtils } from '../../base/ColorUtils.js'; -import { log } from '../../../../../log/Log.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabCpuAbilityData } from '../../../../database/SqlLite'; +import { SystemCpuSummary } from '../../../../bean/AbilityMonitor'; +import { Utils } from '../../base/Utils'; +import { ColorUtils } from '../../base/ColorUtils'; +import { log } from '../../../../../log/Log'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-cpu-ability') export class TabPaneCpuAbility extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneDiskAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneDiskAbility.ts index a295d77b7..c259c007b 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneDiskAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneDiskAbility.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabDiskAbilityData } from '../../../../database/SqlLite.js'; -import { SystemDiskIOSummary } from '../../../../bean/AbilityMonitor.js'; -import { Utils } from '../../base/Utils.js'; -import { ColorUtils } from '../../base/ColorUtils.js'; -import { log } from '../../../../../log/Log.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabDiskAbilityData } from '../../../../database/SqlLite'; +import { SystemDiskIOSummary } from '../../../../bean/AbilityMonitor'; +import { Utils } from '../../base/Utils'; +import { ColorUtils } from '../../base/ColorUtils'; +import { log } from '../../../../../log/Log'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-disk-ability') export class TabPaneDiskAbility extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbility.ts index 472b61b93..7e55d1ba3 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbility.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { Dma } from '../../../../bean/AbilityMonitor.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { getTabDmaAbilityData } from '../../../../database/SqlLite.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { Dma } from '../../../../bean/AbilityMonitor'; +import { resizeObserver } from '../SheetUtils'; +import { getTabDmaAbilityData } from '../../../../database/SqlLite'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { Utils } from '../../base/Utils'; @element('tabpane-dma-ability') export class TabPaneDmaAbility extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbilityComparison.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbilityComparison.ts index 7d1d310e9..fd145f63a 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbilityComparison.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbilityComparison.ts @@ -13,17 +13,17 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitSelect } from '../../../../../base-ui/select/LitSelect.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { DmaComparison } from '../../../../bean/AbilityMonitor.js'; -import { getTabDmaAbilityComparisonData } from '../../../../database/SqlLite.js'; -import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot.js'; -import { Utils } from '../../base/Utils.js'; -import { compare, resizeObserverFromMemory } from '../SheetUtils.js'; -import '../TabPaneJsMemoryFilter.js'; -import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { DmaComparison } from '../../../../bean/AbilityMonitor'; +import { getTabDmaAbilityComparisonData } from '../../../../database/SqlLite'; +import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot'; +import { Utils } from '../../base/Utils'; +import { compare, resizeObserverFromMemory } from '../SheetUtils'; +import '../TabPaneJsMemoryFilter'; +import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; @element('tabpane-dma-ability-comparison') export class TabPaneDmaAbilityComparison extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaSelectAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaSelectAbility.ts index 64852bcbd..0c705852a 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaSelectAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaSelectAbility.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type Dma } from '../../../../bean/AbilityMonitor.js'; -import { getTabDmaAbilityClickData } from '../../../../database/SqlLite.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type Dma } from '../../../../bean/AbilityMonitor'; +import { getTabDmaAbilityClickData } from '../../../../database/SqlLite'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { Utils } from '../../base/Utils'; @element('tabpane-dma-selection-ability') export class TabPaneDmaSelectAbility extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemoryAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemoryAbility.ts index a89300178..a27a2e6cf 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemoryAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemoryAbility.ts @@ -13,16 +13,16 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { GpuMemory } from '../../../../bean/AbilityMonitor.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { getTabGpuMemoryAbilityData } from '../../../../database/SqlLite.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { Utils } from '../../base/Utils.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { GpuMemory } from '../../../../bean/AbilityMonitor'; +import { resizeObserver } from '../SheetUtils'; +import { getTabGpuMemoryAbilityData } from '../../../../database/SqlLite'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { Utils } from '../../base/Utils'; +import { SpSystemTrace } from '../../../SpSystemTrace'; @element('tabpane-gpu-memory-ability') export class TabPaneGpuMemoryAbility extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemoryComparison.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemoryComparison.ts index dc97d6a15..05dcc9b27 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemoryComparison.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemoryComparison.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitSelect } from '../../../../../base-ui/select/LitSelect.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { GpuMemoryComparison } from '../../../../bean/AbilityMonitor.js'; -import { getTabGpuMemoryComparisonData } from '../../../../database/SqlLite.js'; -import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { Utils } from '../../base/Utils.js'; -import { compare, resizeObserverFromMemory } from '../SheetUtils.js'; -import '../TabPaneJsMemoryFilter.js'; -import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { GpuMemoryComparison } from '../../../../bean/AbilityMonitor'; +import { getTabGpuMemoryComparisonData } from '../../../../database/SqlLite'; +import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { Utils } from '../../base/Utils'; +import { compare, resizeObserverFromMemory } from '../SheetUtils'; +import '../TabPaneJsMemoryFilter'; +import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; @element('tabpane-gpu-memory-comparison') export class TabPaneGpuMemoryComparison extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemorySelectAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemorySelectAbility.ts index 0cd5617ee..fadb4f13a 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemorySelectAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneGpuMemorySelectAbility.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type GpuMemory } from '../../../../bean/AbilityMonitor.js'; -import { getTabGpuMemoryAbilityClickData } from '../../../../database/SqlLite.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type GpuMemory } from '../../../../bean/AbilityMonitor'; +import { getTabGpuMemoryAbilityClickData } from '../../../../database/SqlLite'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { Utils } from '../../base/Utils'; @element('tabpane-gpu-memory-selection-ability') export class TabPaneGpuMemorySelectAbility extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneHistoryProcesses.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneHistoryProcesses.ts index 31dc1b0f5..6cdf5dc66 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneHistoryProcesses.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneHistoryProcesses.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabProcessHistoryData } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { ProcessHistory } from '../../../../bean/AbilityMonitor.js'; -import { log } from '../../../../../log/Log.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabProcessHistoryData } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { ProcessHistory } from '../../../../bean/AbilityMonitor'; +import { log } from '../../../../../log/Log'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-history-processes') export class TabPaneHistoryProcesses extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneLiveProcesses.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneLiveProcesses.ts index 9042fd211..ba7ba7c06 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneLiveProcesses.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneLiveProcesses.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabLiveProcessData } from '../../../../database/SqlLite.js'; -import { LiveProcess } from '../../../../bean/AbilityMonitor.js'; -import { Utils } from '../../base/Utils.js'; -import { log } from '../../../../../log/Log.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabLiveProcessData } from '../../../../database/SqlLite'; +import { LiveProcess } from '../../../../bean/AbilityMonitor'; +import { Utils } from '../../base/Utils'; +import { log } from '../../../../../log/Log'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-live-processes') export class TabPaneLiveProcesses extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneMemoryAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneMemoryAbility.ts index 6c44e049f..ca6c6d182 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneMemoryAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneMemoryAbility.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabMemoryAbilityData, queryStartTime } from '../../../../database/SqlLite.js'; -import { SystemMemorySummary } from '../../../../bean/AbilityMonitor.js'; -import { Utils } from '../../base/Utils.js'; -import { log } from '../../../../../log/Log.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabMemoryAbilityData, queryStartTime } from '../../../../database/SqlLite'; +import { SystemMemorySummary } from '../../../../bean/AbilityMonitor'; +import { Utils } from '../../base/Utils'; +import { log } from '../../../../../log/Log'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-memory-ability') export class TabPaneMemoryAbility extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneNetworkAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneNetworkAbility.ts index ce1b7c4fc..5906da1aa 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneNetworkAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneNetworkAbility.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabNetworkAbilityData } from '../../../../database/SqlLite.js'; -import { SystemNetworkSummary } from '../../../../bean/AbilityMonitor.js'; -import { Utils } from '../../base/Utils.js'; -import { ColorUtils } from '../../base/ColorUtils.js'; -import { log } from '../../../../../log/Log.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabNetworkAbilityData } from '../../../../database/SqlLite'; +import { SystemNetworkSummary } from '../../../../bean/AbilityMonitor'; +import { Utils } from '../../base/Utils'; +import { ColorUtils } from '../../base/ColorUtils'; +import { log } from '../../../../../log/Log'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-network-ability') export class TabPaneNetworkAbility extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPanePurgPin.ts b/ide/src/trace/component/trace/sheet/ability/TabPanePurgPin.ts index 87db520d5..7766e44b0 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPanePurgPin.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPanePurgPin.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { queryProcessPurgeableTab, querySysPurgeableTab } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { PurgeableTabStruct } from './TabPanePurgTotal.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { queryProcessPurgeableTab, querySysPurgeableTab } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; +import { PurgeableTabStruct } from './TabPanePurgTotal'; @element('tabpane-purg-pin') export class TabPanePurgPin extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinComparisonAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinComparisonAbility.ts index f29bba5f2..66be75298 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinComparisonAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinComparisonAbility.ts @@ -12,15 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitSelect } from '../../../../../base-ui/select/LitSelect.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { querySysPurgeableSelectionTab } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { CompareStruct, compare, resizeObserverFromMemory } from '../SheetUtils.js'; -import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { querySysPurgeableSelectionTab } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { CompareStruct, compare, resizeObserverFromMemory } from '../SheetUtils'; +import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; @element('tabpane-purgeable-pin-comparison-ability') export class TabPanePurgPinComparisonAbility extends BaseElement { private purgeablePinTable: LitTable | null | undefined; diff --git a/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinSelection.ts b/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinSelection.ts index ad11968a7..b77e9cda1 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinSelection.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinSelection.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { queryProcessPurgeableSelectionTab, querySysPurgeableSelectionTab } from '../../../../database/SqlLite.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { queryProcessPurgeableSelectionTab, querySysPurgeableSelectionTab } from '../../../../database/SqlLite'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-purg-pin-selection') export class TabPanePurgPinSelection extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotal.ts b/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotal.ts index 866804c83..b8239445b 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotal.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotal.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { querySysPurgeableTab, queryProcessPurgeableTab } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { querySysPurgeableTab, queryProcessPurgeableTab } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-purg-total') export class TabPanePurgTotal extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotalComparisonAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotalComparisonAbility.ts index 43ef75b5b..4d2180882 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotalComparisonAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotalComparisonAbility.ts @@ -12,15 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitSelect } from '../../../../../base-ui/select/LitSelect.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { querySysPurgeableSelectionTab } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { CompareStruct, compare, resizeObserverFromMemory } from '../SheetUtils.js'; -import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { querySysPurgeableSelectionTab } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { CompareStruct, compare, resizeObserverFromMemory } from '../SheetUtils'; +import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; @element('tabpane-purgeable-total-comparison-ability') export class TabPanePurgTotalComparisonAbility extends BaseElement { private purgeableTotalTable: LitTable | null | undefined; diff --git a/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotalSelection.ts b/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotalSelection.ts index e12941a55..fb94b7968 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotalSelection.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPanePurgTotalSelection.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { queryProcessPurgeableSelectionTab, querySysPurgeableSelectionTab } from '../../../../database/SqlLite.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { queryProcessPurgeableSelectionTab, querySysPurgeableSelectionTab } from '../../../../database/SqlLite'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-purg-total-selection') export class TabPanePurgTotalSelection extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneComparison.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneComparison.ts index 11c090a40..cf69d4b33 100644 --- a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneComparison.ts +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneComparison.ts @@ -13,17 +13,17 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { HeapDataInterface } from '../../../../../js-heap/HeapDataInterface.js'; -import { ConstructorComparison, ConstructorItem, ConstructorType } from '../../../../../js-heap/model/UiStruct.js'; -import { LitTableColumn } from '../../../../../base-ui/table/lit-table-column.js'; -import '../../../../../base-ui/table/lit-table-column.js'; -import { TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; -import '../TabPaneJsMemoryFilter.js'; -import { HeapSnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerHeapSnapshot.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { LitSelect } from '../../../../../base-ui/select/LitSelect.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { HeapDataInterface } from '../../../../../js-heap/HeapDataInterface'; +import { ConstructorComparison, ConstructorItem, ConstructorType } from '../../../../../js-heap/model/UiStruct'; +import { LitTableColumn } from '../../../../../base-ui/table/lit-table-column'; +import '../../../../../base-ui/table/lit-table-column'; +import { TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; +import '../TabPaneJsMemoryFilter'; +import { HeapSnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerHeapSnapshot'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { LitSelect } from '../../../../../base-ui/select/LitSelect'; @element('tabpane-comparison') export class TabPaneComparison extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts index 45a53eefa..fb9bfc5c6 100644 --- a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable, TableMode } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { type JsCpuProfilerChartFrame, JsCpuProfilerTabStruct } from '../../../../bean/JsStruct.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { findSearchNode, ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { type FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import '../TabPaneFilter.js'; +import { BaseElement } from '../../../../../base-ui/BaseElement'; +import { type LitTable, TableMode } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { type JsCpuProfilerChartFrame, JsCpuProfilerTabStruct } from '../../../../bean/JsStruct'; +import { procedurePool } from '../../../../database/Procedure'; +import { findSearchNode, ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { type FilterData, TabPaneFilter } from '../TabPaneFilter'; +import '../TabPaneFilter'; export class TabPaneJsCpuCallTree extends BaseElement { protected TYPE_TOP_DOWN = 0; diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuBottomUp.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuBottomUp.ts index c17e86e4b..ba1dd2f6f 100644 --- a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuBottomUp.ts +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuBottomUp.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { element } from '../../../../../base-ui/BaseElement.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { type JsCpuProfilerChartFrame } from '../../../../bean/JsStruct.js'; -import { TabPaneJsCpuCallTree } from './TabPaneJsCpu.js'; +import { element } from '../../../../../base-ui/BaseElement'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { type JsCpuProfilerChartFrame } from '../../../../bean/JsStruct'; +import { TabPaneJsCpuCallTree } from './TabPaneJsCpu'; @element('tabpane-js-cpu-bottom-up') export class TabPaneJsCpuBottomUp extends TabPaneJsCpuCallTree { diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuCallTree.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuCallTree.ts index 585603c10..77ac60498 100644 --- a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuCallTree.ts +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuCallTree.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { element } from '../../../../../base-ui/BaseElement.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { type JsCpuProfilerChartFrame } from '../../../../bean/JsStruct.js'; -import { TabPaneJsCpuCallTree } from './TabPaneJsCpu.js'; +import { element } from '../../../../../base-ui/BaseElement'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { type JsCpuProfilerChartFrame } from '../../../../bean/JsStruct'; +import { TabPaneJsCpuCallTree } from './TabPaneJsCpu'; @element('tabpane-js-cpu-top-down') export class TabPaneJsCpuTopDown extends TabPaneJsCpuCallTree { diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuStatistics.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuStatistics.ts index 69c37acb3..2fdd9e3ae 100644 --- a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuStatistics.ts +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuStatistics.ts @@ -13,16 +13,16 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie.js'; -import { type LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { type JsCpuProfilerChartFrame, JsCpuProfilerStatisticsStruct } from '../../../../bean/JsStruct.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { type SampleType } from '../../../../database/logic-worker/ProcedureLogicWorkerJsCpuProfiler.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie'; +import { type LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { type JsCpuProfilerChartFrame, JsCpuProfilerStatisticsStruct } from '../../../../bean/JsStruct'; +import { procedurePool } from '../../../../database/Procedure'; +import { type SampleType } from '../../../../database/logic-worker/ProcedureLogicWorkerJsCpuProfiler'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-js-cpu-statistics') export class TabPaneJsCpuStatistics extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneSummary.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneSummary.ts index 473b7ed4f..8eba4f982 100644 --- a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneSummary.ts +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneSummary.ts @@ -13,19 +13,19 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import '../../../../../base-ui/table/lit-table.js'; -import { type ConstructorItem, FileInfo } from '../../../../../js-heap/model/UiStruct.js'; -import { HeapDataInterface } from '../../../../../js-heap/HeapDataInterface.js'; -import '../../../../../base-ui/table/lit-table-column.js'; -import { TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; -import '../TabPaneJsMemoryFilter.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import '../../../../../base-ui/slicer/lit-slicer.js'; -import { HeapSnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerHeapSnapshot.js'; -import { HeapTraceFunctionInfo } from '../../../../../js-heap/model/DatabaseStruct.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import '../../../../../base-ui/table/lit-table'; +import { type ConstructorItem, FileInfo } from '../../../../../js-heap/model/UiStruct'; +import { HeapDataInterface } from '../../../../../js-heap/HeapDataInterface'; +import '../../../../../base-ui/table/lit-table-column'; +import { TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; +import '../TabPaneJsMemoryFilter'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import '../../../../../base-ui/progress-bar/LitProgressBar'; +import '../../../../../base-ui/slicer/lit-slicer'; +import { HeapSnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerHeapSnapshot'; +import { HeapTraceFunctionInfo } from '../../../../../js-heap/model/DatabaseStruct'; @element('tabpane-summary') export class TabPaneSummary extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/clock/TabPaneClockCounter.ts b/ide/src/trace/component/trace/sheet/clock/TabPaneClockCounter.ts index d7113aeea..7d1b6d2cd 100644 --- a/ide/src/trace/component/trace/sheet/clock/TabPaneClockCounter.ts +++ b/ide/src/trace/component/trace/sheet/clock/TabPaneClockCounter.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { Counter, SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { Counter, SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-clock-counter') export class TabPaneClockCounter extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneBoxChild.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneBoxChild.ts index b726a4f65..232fa680b 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneBoxChild.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneBoxChild.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { BoxJumpParam, SelectionData } from '../../../../bean/BoxSelection.js'; -import { getTabBoxChildData } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { SPTChild } from '../../../../bean/StateProcessThread.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { BoxJumpParam, SelectionData } from '../../../../bean/BoxSelection'; +import { getTabBoxChildData } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { SPTChild } from '../../../../bean/StateProcessThread'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-box-child') export class TabPaneBoxChild extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts index be23bba72..1ccb2edf1 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts @@ -13,19 +13,19 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabPaneCounterSampleData } from '../../../../database/SqlLite.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { dataFilterHandler, drawLines } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { TraceRow } from '../../base/TraceRow.js'; -import { CpuFreqStruct } from '../../../../database/ui-worker/ProcedureWorkerFreq.js'; -import { CpuState } from '../../../../database/logic-worker/ProcedureLogicWorkerCpuState.js'; -import { CpuStateStruct } from '../../../../database/ui-worker/ProcedureWorkerCpuState.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabPaneCounterSampleData } from '../../../../database/SqlLite'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { dataFilterHandler, drawLines } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { TraceRow } from '../../base/TraceRow'; +import { CpuFreqStruct } from '../../../../database/ui-worker/ProcedureWorkerFreq'; +import { CpuState } from '../../../../database/logic-worker/ProcedureLogicWorkerCpuState'; +import { CpuStateStruct } from '../../../../database/ui-worker/ProcedureWorkerCpuState'; @element('tabpane-counter-sample') export class TabPaneCounterSample extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByProcess.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByProcess.ts index eff4585fd..5776e8c2b 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByProcess.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByProcess.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabCpuByProcess } from '../../../../database/SqlLite.js'; -import { log } from '../../../../../log/Log.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabCpuByProcess } from '../../../../database/SqlLite'; +import { log } from '../../../../../log/Log'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-cpu-process') export class TabPaneCpuByProcess extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByThread.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByThread.ts index ed3401bf2..b4317de41 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByThread.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByThread.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabCpuByThread } from '../../../../database/SqlLite.js'; -import { log } from '../../../../../log/Log.js'; -import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabCpuByThread } from '../../../../database/SqlLite'; +import { log } from '../../../../../log/Log'; +import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-cpu-thread') export class TabPaneCpuByThread extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuStateClick.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuStateClick.ts index 99cb870d9..28f2f744a 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuStateClick.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuStateClick.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-cpu-state-click') export class TabPaneCpuStateClick extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuUsage.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuUsage.ts index 2d99bd6eb..b25a44cdb 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuUsage.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuUsage.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabCpuFreq, getTabCpuUsage } from '../../../../database/SqlLite.js'; -import { CpuUsage, Freq } from '../../../../bean/CpuUsage.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabCpuFreq, getTabCpuUsage } from '../../../../database/SqlLite'; +import { CpuUsage, Freq } from '../../../../bean/CpuUsage'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-cpu-usage') export class TabPaneCpuUsage extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts index 44069d6cf..81d015b1c 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts @@ -12,19 +12,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabPaneFrequencySampleData, getTabPaneCounterSampleData } from '../../../../database/SqlLite.js'; -import { ColorUtils } from '../../base/ColorUtils.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { CpuFreqStruct } from '../../../../database/ui-worker/ProcedureWorkerFreq.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { TraceRow } from '../../base/TraceRow.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabPaneFrequencySampleData, getTabPaneCounterSampleData } from '../../../../database/SqlLite'; +import { ColorUtils } from '../../base/ColorUtils'; +import { resizeObserver } from '../SheetUtils'; +import { CpuFreqStruct } from '../../../../database/ui-worker/ProcedureWorkerFreq'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { TraceRow } from '../../base/TraceRow'; import { drawLines, -} from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; +} from '../../../../database/ui-worker/ProcedureWorkerCommon'; @element('tabpane-frequency-sample') export class TabPaneFrequencySample extends BaseElement { @@ -187,7 +186,7 @@ export class TabPaneFrequencySample extends BaseElement { stateFiliterIds ); //开启一个线程计算busyTime - this.worker = new Worker('trace/database/StateBusyTimeWorker.js'); + this.worker = new Worker(new URL('../../../../database/StateBusyTimeWorker',import.meta.url)); let msg = { frqSampleParam, result, diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPanePTS.ts b/ide/src/trace/component/trace/sheet/cpu/TabPanePTS.ts index 8f1d525b0..61f78e9a7 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPanePTS.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPanePTS.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { Utils } from '../../base/Utils.js'; -import { SliceGroup } from '../../../../bean/StateProcessThread.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { resizeObserver } from '../SheetUtils'; +import { procedurePool } from '../../../../database/Procedure'; +import { Utils } from '../../base/Utils'; +import { SliceGroup } from '../../../../bean/StateProcessThread'; @element('tabpane-pts') export class TabPanePTS extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneSPT.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneSPT.ts index b3997a386..dc2aa50f9 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneSPT.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneSPT.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { SliceGroup } from '../../../../bean/StateProcessThread.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { SliceGroup } from '../../../../bean/StateProcessThread'; +import { resizeObserver } from '../SheetUtils'; +import { procedurePool } from '../../../../database/Procedure'; +import { Utils } from '../../base/Utils'; @element('tabpane-spt') export class TabPaneSPT extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneSchedPriority.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneSchedPriority.ts index 6173e3ad8..a50f76775 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneSchedPriority.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneSchedPriority.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { Utils } from '../../base/Utils.js'; -import { queryThreadStateArgsByName } from '../../../../database/SqlLite.js'; -import { Priority } from '../../../../bean/StateProcessThread.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { resizeObserver } from '../SheetUtils'; +import { procedurePool } from '../../../../database/Procedure'; +import { Utils } from '../../base/Utils'; +import { queryThreadStateArgsByName } from '../../../../database/SqlLite'; +import { Priority } from '../../../../bean/StateProcessThread'; @element('tabpane-sched-priority') export class TabPaneSchedPriority extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/energy/TabPaneEnergyAnomaly.ts b/ide/src/trace/component/trace/sheet/energy/TabPaneEnergyAnomaly.ts index a486f5608..7751905f6 100644 --- a/ide/src/trace/component/trace/sheet/energy/TabPaneEnergyAnomaly.ts +++ b/ide/src/trace/component/trace/sheet/energy/TabPaneEnergyAnomaly.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; -import { queryAnomalyDetailedData } from '../../../../database/SqlLite.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { EnergyAnomalyStruct } from '../../../../database/ui-worker/ProcedureWorkerEnergyAnomaly.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { queryAnomalyDetailedData } from '../../../../database/SqlLite'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { EnergyAnomalyStruct } from '../../../../database/ui-worker/ProcedureWorkerEnergyAnomaly'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-anomaly-details') export class TabPaneEnergyAnomaly extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/energy/TabPanePowerBattery.ts b/ide/src/trace/component/trace/sheet/energy/TabPanePowerBattery.ts index b4e409731..c91890817 100644 --- a/ide/src/trace/component/trace/sheet/energy/TabPanePowerBattery.ts +++ b/ide/src/trace/component/trace/sheet/energy/TabPanePowerBattery.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabPowerBatteryData } from '../../../../database/SqlLite.js'; -import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart.js'; -import '../../../../../base-ui/table/lit-table.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabPowerBatteryData } from '../../../../database/SqlLite'; +import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart'; +import '../../../../../base-ui/table/lit-table'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-power-battery') export class TabPanePowerBattery extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/energy/TabPanePowerDetails.ts b/ide/src/trace/component/trace/sheet/energy/TabPanePowerDetails.ts index b53a22701..bd31a6818 100644 --- a/ide/src/trace/component/trace/sheet/energy/TabPanePowerDetails.ts +++ b/ide/src/trace/component/trace/sheet/energy/TabPanePowerDetails.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabPowerDetailsData } from '../../../../database/SqlLite.js'; -import { log } from '../../../../../log/Log.js'; -import { PowerDetailsEnergy } from '../../../../bean/EnergyStruct.js'; -import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabPowerDetailsData } from '../../../../database/SqlLite'; +import { log } from '../../../../../log/Log'; +import { PowerDetailsEnergy } from '../../../../bean/EnergyStruct'; +import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-power-details') export class TabPanePowerDetails extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/energy/TabPaneSystemDetails.ts b/ide/src/trace/component/trace/sheet/energy/TabPaneSystemDetails.ts index 5f971e570..dde0764ff 100644 --- a/ide/src/trace/component/trace/sheet/energy/TabPaneSystemDetails.ts +++ b/ide/src/trace/component/trace/sheet/energy/TabPaneSystemDetails.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { SystemDetailsEnergy } from '../../../../bean/EnergyStruct.js'; -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; +import { SystemDetailsEnergy } from '../../../../bean/EnergyStruct'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; import { querySysLocationDetailsData, querySysLockDetailsData, querySystemWorkData, -} from '../../../../database/SqlLite.js'; -import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { type LitSlicerTrack } from '../../../../../base-ui/slicer/lit-slicer.js'; +} from '../../../../database/SqlLite'; +import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart'; +import { resizeObserver } from '../SheetUtils'; +import { type LitSlicerTrack } from '../../../../../base-ui/slicer/lit-slicer'; @element('tabpane-system-details') export class TabPaneSystemDetails extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts index 58dfb2521..f584d8cb8 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts @@ -13,19 +13,19 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { FrameChart } from '../../../chart/FrameChart.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { ChartMode } from '../../../../bean/FrameChartStruct.js'; -import { FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { MerageBean } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { showButtonMenu } from '../SheetUtils.js'; -import { CallTreeLevelStruct } from '../../../../bean/EbpfStruct.js'; -import '../../../../../base-ui/headline/lit-headline.js'; -import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { FrameChart } from '../../../chart/FrameChart'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { ChartMode } from '../../../../bean/FrameChartStruct'; +import { FilterData, TabPaneFilter } from '../TabPaneFilter'; +import { procedurePool } from '../../../../database/Procedure'; +import { MerageBean } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { showButtonMenu } from '../SheetUtils'; +import { CallTreeLevelStruct } from '../../../../bean/EbpfStruct'; +import '../../../../../base-ui/headline/lit-headline'; +import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline'; const InvertOptionIndex: number = 0; const hideEventOptionIndex: number = 2; diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts index b47dcc8c2..514e87b91 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts @@ -13,21 +13,21 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { FrameChart } from '../../../chart/FrameChart.js'; -import '../../../chart/FrameChart.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { ChartMode } from '../../../../bean/FrameChartStruct.js'; -import { FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import '../TabPaneFilter.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { FileMerageBean } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem.js'; -import { showButtonMenu } from '../SheetUtils.js'; -import { CallTreeLevelStruct } from '../../../../bean/EbpfStruct.js'; -import '../../../../../base-ui/headline/lit-headline.js'; -import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { FrameChart } from '../../../chart/FrameChart'; +import '../../../chart/FrameChart'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { ChartMode } from '../../../../bean/FrameChartStruct'; +import { FilterData, TabPaneFilter } from '../TabPaneFilter'; +import '../TabPaneFilter'; +import { procedurePool } from '../../../../database/Procedure'; +import { FileMerageBean } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; +import { showButtonMenu } from '../SheetUtils'; +import { CallTreeLevelStruct } from '../../../../bean/EbpfStruct'; +import '../../../../../base-ui/headline/lit-headline'; +import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline'; const InvertOptionIndex: number = 0; const hideEventOptionIndex: number = 2; diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescHistory.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescHistory.ts index ef08cf519..f6344b215 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescHistory.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescHistory.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../../../base-ui/slicer/lit-slicer.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import { FileSysEvent } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem.js'; -import { procedurePool } from '../../../../database/Procedure.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../../../base-ui/slicer/lit-slicer'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { FilterData, TabPaneFilter } from '../TabPaneFilter'; +import { FileSysEvent } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; +import { procedurePool } from '../../../../database/Procedure'; @element('tabpane-filesystem-desc-history') export class TabPaneFileSystemDescHistory extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescTimeSlice.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescTimeSlice.ts index f54abc99d..f20b095c9 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescTimeSlice.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescTimeSlice.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../../../base-ui/slicer/lit-slicer.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { FileSysEvent } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem.js'; -import { procedurePool } from '../../../../database/Procedure.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../../../base-ui/slicer/lit-slicer'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { FileSysEvent } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; +import { procedurePool } from '../../../../database/Procedure'; @element('tabpane-filesystem-desc-time-slice') export class TabPaneFileSystemDescTimeSlice extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemEvents.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemEvents.ts index 44460346c..a42f94185 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemEvents.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemEvents.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../../../base-ui/slicer/lit-slicer.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { FileSysEvent } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem.js'; -import { FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import '../TabPaneFilter.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../../../base-ui/slicer/lit-slicer'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { procedurePool } from '../../../../database/Procedure'; +import { FileSysEvent } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; +import { FilterData, TabPaneFilter } from '../TabPaneFilter'; +import '../TabPaneFilter'; @element('tabpane-filesystem-event') export class TabPaneFileSystemEvents extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatistics.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatistics.ts index eddd56dd2..2ae7372ad 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatistics.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatistics.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabPaneFilesystemStatistics } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabPaneFilesystemStatistics } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; @element('tabpane-file-statistics') export class TabPaneFileStatistics extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts index 677b27a3f..283ec7acc 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../../../base-ui/chart/pie/LitChartPie.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../../../base-ui/chart/pie/LitChartPie'; import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; -import { Utils } from '../../base/Utils.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox.js'; -import { TabPaneFilter } from '../TabPaneFilter.js'; -import { initSort } from '../SheetUtils.js'; -import { TabpaneFilesystemCalltree } from './TabPaneFileSystemCalltree.js'; +import { Utils } from '../../base/Utils'; +import { procedurePool } from '../../../../database/Procedure'; +import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox'; +import { TabPaneFilter } from '../TabPaneFilter'; +import { initSort } from '../SheetUtils'; +import { TabpaneFilesystemCalltree } from './TabPaneFileSystemCalltree'; @element('tabpane-file-statistics-analysis') export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneIOCallTree.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOCallTree.ts index 9cf831070..92a1ecc16 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneIOCallTree.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOCallTree.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import './TabPaneCallTree.js'; -import { TabPaneCallTree } from './TabPaneCallTree.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import './TabPaneCallTree'; +import { TabPaneCallTree } from './TabPaneCallTree'; @element('tabpane-io-calltree') export class TabPaneIOCallTree extends TabPaneCallTree { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatistics.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatistics.ts index 6562632a1..d155ae4c6 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatistics.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatistics.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabPaneIOTierStatisticsData } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { TabPaneFilter } from '../TabPaneFilter.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabPaneIOTierStatisticsData } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { TabPaneFilter } from '../TabPaneFilter'; +import { SpSystemTrace } from '../../../SpSystemTrace'; @element('tabpane-io-tier-statistics') export class TabPaneIOTierStatistics extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts index 0fb0b6eba..7521c71c6 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie.js'; -import '../../../../../base-ui/chart/pie/LitChartPie.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie'; +import '../../../../../base-ui/chart/pie/LitChartPie'; +import { SelectionParam } from '../../../../bean/BoxSelection'; import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; -import { Utils } from '../../base/Utils.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox.js'; -import { TabPaneFilter } from '../TabPaneFilter.js'; -import { initSort } from '../SheetUtils.js'; -import { TabPaneIOCallTree } from './TabPaneIOCallTree.js'; +import { Utils } from '../../base/Utils'; +import { procedurePool } from '../../../../database/Procedure'; +import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox'; +import { TabPaneFilter } from '../TabPaneFilter'; +import { initSort } from '../SheetUtils'; +import { TabPaneIOCallTree } from './TabPaneIOCallTree'; @element('tabpane-tb-vm-statistics') export class TabPaneIOTierStatisticsAnalysis extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneIoCompletionTimes.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneIoCompletionTimes.ts index 0acaca49b..57fa58e7a 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneIoCompletionTimes.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneIoCompletionTimes.ts @@ -13,19 +13,19 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../../../base-ui/slicer/lit-slicer.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { procedurePool } from '../../../../database/Procedure.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../../../base-ui/slicer/lit-slicer'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { procedurePool } from '../../../../database/Procedure'; import { FileSysEvent, IoCompletionTimes, VM_TYPE_MAP, -} from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem.js'; -import { FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import { getTabIoCompletionTimesType } from '../../../../database/SqlLite.js'; +} from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; +import { FilterData, TabPaneFilter } from '../TabPaneFilter'; +import { getTabIoCompletionTimesType } from '../../../../database/SqlLite'; @element('tabpane-io-completiontimes') export class TabPaneIoCompletionTimes extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneVMEvents.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneVMEvents.ts index 18da8baa6..af97a433f 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneVMEvents.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneVMEvents.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../../../base-ui/slicer/lit-slicer.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { VirtualMemoryEvent, VM_TYPE_MAP } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem.js'; -import { FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import { getTabVirtualMemoryType } from '../../../../database/SqlLite.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../../../base-ui/slicer/lit-slicer'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { procedurePool } from '../../../../database/Procedure'; +import { VirtualMemoryEvent, VM_TYPE_MAP } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; +import { FilterData, TabPaneFilter } from '../TabPaneFilter'; +import { getTabVirtualMemoryType } from '../../../../database/SqlLite'; @element('tabpane-virtualmemory-event') export class TabPaneVirtualMemoryEvents extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatistics.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatistics.ts index 144116261..943c7961f 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatistics.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatistics.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabPaneVirtualMemoryStatisticsData } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { TabPaneFilter } from '../TabPaneFilter.js'; -import '../TabPaneFilter.js'; -import { VM_TYPE_MAP } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabPaneVirtualMemoryStatisticsData } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { TabPaneFilter } from '../TabPaneFilter'; +import '../TabPaneFilter'; +import { VM_TYPE_MAP } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; @element('tabpane-virtual-memory-statistics') export class TabPaneVirtualMemoryStatistics extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts index db1c38819..3679a3f57 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie.js'; -import '../../../../../base-ui/chart/pie/LitChartPie.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie'; +import '../../../../../base-ui/chart/pie/LitChartPie'; import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; -import { Utils } from '../../base/Utils.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox.js'; -import { TabPaneFilter } from '../TabPaneFilter.js'; -import { initSort } from '../SheetUtils.js'; -import { TabPaneVMCallTree } from './TabPaneIOCallTree.js'; +import { Utils } from '../../base/Utils'; +import { procedurePool } from '../../../../database/Procedure'; +import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox'; +import { TabPaneFilter } from '../TabPaneFilter'; +import { initSort } from '../SheetUtils'; +import { TabPaneVMCallTree } from './TabPaneIOCallTree'; @element('tabpane-virtual-memory-statistics-analysis') export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/fps/TabPaneFps.ts b/ide/src/trace/component/trace/sheet/fps/TabPaneFps.ts index 909a97ad6..c20ea92c0 100644 --- a/ide/src/trace/component/trace/sheet/fps/TabPaneFps.ts +++ b/ide/src/trace/component/trace/sheet/fps/TabPaneFps.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabFps } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { log } from '../../../../../log/Log.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabFps } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { log } from '../../../../../log/Log'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-fps') export class TabPaneFps extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/frame/TabFrameSpacing.ts b/ide/src/trace/component/trace/sheet/frame/TabFrameSpacing.ts index bce670668..a81ea2165 100644 --- a/ide/src/trace/component/trace/sheet/frame/TabFrameSpacing.ts +++ b/ide/src/trace/component/trace/sheet/frame/TabFrameSpacing.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { FrameSpacingStruct } from '../../../../database/ui-worker/ProcedureWorkerFrameSpacing.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { FrameSpacingStruct } from '../../../../database/ui-worker/ProcedureWorkerFrameSpacing'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { resizeObserver } from '../SheetUtils'; +import { Utils } from '../../base/Utils'; @element('tabpane-frames-spacing') export class TabFrameSpacing extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/frame/TabPaneFrameDynamic.ts b/ide/src/trace/component/trace/sheet/frame/TabPaneFrameDynamic.ts index c0464dcbc..0d869989d 100644 --- a/ide/src/trace/component/trace/sheet/frame/TabPaneFrameDynamic.ts +++ b/ide/src/trace/component/trace/sheet/frame/TabPaneFrameDynamic.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { type FrameDynamicStruct } from '../../../../database/ui-worker/ProcedureWorkerFrameDynamic.js'; -import { type FrameAnimationSelect } from '../../../../bean/FrameComponentBean.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { resizeObserver } from '../SheetUtils'; +import { type FrameDynamicStruct } from '../../../../database/ui-worker/ProcedureWorkerFrameDynamic'; +import { type FrameAnimationSelect } from '../../../../bean/FrameComponentBean'; +import { Utils } from '../../base/Utils'; @element('tabpane-frame-dynamic') export class TabPaneFrameDynamic extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/freq/TabPaneCpuFreqLimits.ts b/ide/src/trace/component/trace/sheet/freq/TabPaneCpuFreqLimits.ts index 26b893b49..0f28cfa15 100644 --- a/ide/src/trace/component/trace/sheet/freq/TabPaneCpuFreqLimits.ts +++ b/ide/src/trace/component/trace/sheet/freq/TabPaneCpuFreqLimits.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { Utils } from '../../base/Utils.js'; -import { ColorUtils } from '../../base/ColorUtils.js'; -import { CpuFreqLimitsStruct } from '../../../../database/ui-worker/ProcedureWorkerCpuFreqLimits.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { Utils } from '../../base/Utils'; +import { ColorUtils } from '../../base/ColorUtils'; +import { CpuFreqLimitsStruct } from '../../../../database/ui-worker/ProcedureWorkerCpuFreqLimits'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-cpu-freq-limits') export class TabPaneCpuFreqLimits extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/freq/TabPaneFreq.ts b/ide/src/trace/component/trace/sheet/freq/TabPaneFreq.ts index d5d97ffe7..c737a40e1 100644 --- a/ide/src/trace/component/trace/sheet/freq/TabPaneFreq.ts +++ b/ide/src/trace/component/trace/sheet/freq/TabPaneFreq.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { ColorUtils } from '../../base/ColorUtils.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { ColorUtils } from '../../base/ColorUtils'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-freq') export class TabPaneFreq extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/freq/TabPaneFreqLimit.ts b/ide/src/trace/component/trace/sheet/freq/TabPaneFreqLimit.ts index 0c96423c1..23568faa7 100644 --- a/ide/src/trace/component/trace/sheet/freq/TabPaneFreqLimit.ts +++ b/ide/src/trace/component/trace/sheet/freq/TabPaneFreqLimit.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { ColorUtils } from '../../base/ColorUtils.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { ColorUtils } from '../../base/ColorUtils'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-freq-limit') export class TabPaneFreqLimit extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts index 69f4b271d..a63a2519d 100644 --- a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts +++ b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts @@ -13,19 +13,19 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table'; import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; -import '../../../StackBar.js'; +import '../../../StackBar'; import { getTabRunningPercent, querySearchFuncData, queryCpuFreqUsageData, queryCpuFreqFilterId, -} from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { SliceGroup } from '../../../../bean/StateProcessThread.js'; +} from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; +import { SliceGroup } from '../../../../bean/StateProcessThread'; @element('tabpane-freqdatacut') export class TabPaneFreqDataCut extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts index 3cfd8e96c..01460ab36 100644 --- a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts +++ b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../StackBar.js'; -import { getTabRunningPercent, queryCpuFreqUsageData, queryCpuFreqFilterId } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { SliceGroup } from '../../../../bean/StateProcessThread.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table'; +import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../StackBar'; +import { getTabRunningPercent, queryCpuFreqUsageData, queryCpuFreqFilterId } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { resizeObserver } from '../SheetUtils'; +import { SliceGroup } from '../../../../bean/StateProcessThread'; @element('tabpane-frequsage') export class TabPaneFreqUsage extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelect.ts b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelect.ts index 4177f36cc..8171bba7b 100644 --- a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelect.ts +++ b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelect.ts @@ -12,14 +12,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { queryGpuDataByTs } from '../../../../database/SqlLite.js'; -import { VmTrackerChart } from '../../../chart/SpVmTrackerChart.js'; -import { log } from '../../../../../log/Log.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { resizeObserver } from '../SheetUtils'; +import { queryGpuDataByTs } from '../../../../database/SqlLite'; +import { VmTrackerChart } from '../../../chart/SpVmTrackerChart'; +import { log } from '../../../../../log/Log'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { Utils } from '../../base/Utils'; interface GpuTreeItem { name: string; id: number; diff --git a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelectComparison.ts b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelectComparison.ts index 7e800896e..0fe178956 100644 --- a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelectComparison.ts +++ b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelectComparison.ts @@ -12,19 +12,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitSelect } from '../../../../../base-ui/select/LitSelect.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { queryGpuDataByTs } from '../../../../database/SqlLite.js'; -import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot.js'; -import { VmTrackerChart } from '../../../chart/SpVmTrackerChart.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { Utils } from '../../base/Utils.js'; -import { compare, CompareStruct, resizeObserverFromMemory } from '../SheetUtils.js'; -import '../TabPaneJsMemoryFilter.js'; -import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; -import { TabPaneGpuClickSelect } from './TabPaneGpuClickSelect.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { queryGpuDataByTs } from '../../../../database/SqlLite'; +import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot'; +import { VmTrackerChart } from '../../../chart/SpVmTrackerChart'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { Utils } from '../../base/Utils'; +import { compare, CompareStruct, resizeObserverFromMemory } from '../SheetUtils'; +import '../TabPaneJsMemoryFilter'; +import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; +import { TabPaneGpuClickSelect } from './TabPaneGpuClickSelect'; interface GpuTreeItem { name: string; id: number; diff --git a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuGL.ts b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuGL.ts index cf55999f2..29a32b64c 100644 --- a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuGL.ts +++ b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuGL.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { queryGpuDataTab } from '../../../../database/SqlLite.js'; -import { log } from '../../../../../log/Log.js'; -import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { Utils } from '../../base/Utils.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { queryGpuDataTab } from '../../../../database/SqlLite'; +import { log } from '../../../../../log/Log'; +import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { resizeObserver } from '../SheetUtils'; +import { Utils } from '../../base/Utils'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; interface GL { startTs: number; diff --git a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuTotalBoxSelect.ts b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuTotalBoxSelect.ts index ecc02f5d6..1e48185e5 100644 --- a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuTotalBoxSelect.ts +++ b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuTotalBoxSelect.ts @@ -13,16 +13,16 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { queryGpuDataByRange } from '../../../../database/SqlLite.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { log } from '../../../../../log/Log.js'; -import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { queryGpuDataByRange } from '../../../../database/SqlLite'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { log } from '../../../../../log/Log'; +import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { resizeObserver } from '../SheetUtils'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { Utils } from '../../base/Utils'; interface GpuTotal { startTs: number; diff --git a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuWindowBoxSelect.ts b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuWindowBoxSelect.ts index 7b13628ed..c333200c1 100644 --- a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuWindowBoxSelect.ts +++ b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuWindowBoxSelect.ts @@ -13,16 +13,16 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { queryGpuDataByRange } from '../../../../database/SqlLite.js'; -import { log } from '../../../../../log/Log.js'; -import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { queryGpuDataByRange } from '../../../../database/SqlLite'; +import { log } from '../../../../../log/Log'; +import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { resizeObserver } from '../SheetUtils'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { Utils } from '../../base/Utils'; interface Gpu { startTs: number; diff --git a/ide/src/trace/component/trace/sheet/gpu/TabPaneGraph.ts b/ide/src/trace/component/trace/sheet/gpu/TabPaneGraph.ts index 7fe61e25d..a9b1b3f95 100644 --- a/ide/src/trace/component/trace/sheet/gpu/TabPaneGraph.ts +++ b/ide/src/trace/component/trace/sheet/gpu/TabPaneGraph.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { queryGpuDataTab } from '../../../../database/SqlLite.js'; -import { log } from '../../../../../log/Log.js'; -import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { Utils } from '../../base/Utils.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { queryGpuDataTab } from '../../../../database/SqlLite'; +import { log } from '../../../../../log/Log'; +import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { resizeObserver } from '../SheetUtils'; +import { Utils } from '../../base/Utils'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; interface Graph { startTs: number; diff --git a/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogSummary.ts b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogSummary.ts index 3da7ee659..64de128b6 100644 --- a/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogSummary.ts +++ b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogSummary.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { LogStruct } from '../../../../database/ui-worker/ProcedureWorkerLog.js'; -import { ColorUtils } from '../../base/ColorUtils.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { LitIcon } from '../../../../../base-ui/icon/LitIcon.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { LogStruct } from '../../../../database/ui-worker/ProcedureWorkerLog'; +import { ColorUtils } from '../../base/ColorUtils'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { LitIcon } from '../../../../../base-ui/icon/LitIcon'; @element('tab-hi-log-summary') export class TabPaneHiLogSummary extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogs.ts b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogs.ts index cf3b8983c..bb4c18b05 100644 --- a/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogs.ts +++ b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogs.ts @@ -13,16 +13,16 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { TraceRow } from '../../base/TraceRow.js'; -import { TraceSheet } from '../../base/TraceSheet.js'; -import { Flag } from '../../timer-shaft/Flag.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { ns2Timestamp, ns2x, Rect } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { LogStruct } from '../../../../database/ui-worker/ProcedureWorkerLog.js'; -import { ColorUtils } from '../../base/ColorUtils.js'; -import { LitPageTable } from '../../../../../base-ui/table/LitPageTable.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { TraceRow } from '../../base/TraceRow'; +import { TraceSheet } from '../../base/TraceSheet'; +import { Flag } from '../../timer-shaft/Flag'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { ns2Timestamp, ns2x, Rect } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { LogStruct } from '../../../../database/ui-worker/ProcedureWorkerLog'; +import { ColorUtils } from '../../base/ColorUtils'; +import { LitPageTable } from '../../../../../base-ui/table/LitPageTable'; @element('tab-hi-log') export class TabPaneHiLogs extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts index 869e25778..0aff8cc73 100644 --- a/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts @@ -13,17 +13,17 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie.js'; -import '../../../../../base-ui/chart/pie/LitChartPie.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { TabPaneFilter } from '../TabPaneFilter.js'; -import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox.js'; -import { initSort } from '../SheetUtils.js'; -import { TabpanePerfProfile } from './TabPerfProfile.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie'; +import '../../../../../base-ui/chart/pie/LitChartPie'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { procedurePool } from '../../../../database/Procedure'; +import { TabPaneFilter } from '../TabPaneFilter'; +import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox'; +import { initSort } from '../SheetUtils'; +import { TabpanePerfProfile } from './TabPerfProfile'; @element('tabpane-perf-analysis') export class TabPanePerfAnalysis extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts index 0528dedd3..137443c11 100644 --- a/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import '../TabPaneFilter.js'; -import { type FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../chart/FrameChart.js'; -import '../../../../../base-ui/slicer/lit-slicer.js'; -import '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { type LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { type PerfBottomUpStruct } from '../../../../bean/PerfBottomUpStruct.js'; -import { findSearchNode } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import '../TabPaneFilter'; +import { type FilterData, TabPaneFilter } from '../TabPaneFilter'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../chart/FrameChart'; +import '../../../../../base-ui/slicer/lit-slicer'; +import '../../../../../base-ui/progress-bar/LitProgressBar'; +import { procedurePool } from '../../../../database/Procedure'; +import { type LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { type PerfBottomUpStruct } from '../../../../bean/PerfBottomUpStruct'; +import { findSearchNode } from '../../../../database/ui-worker/ProcedureWorkerCommon'; @element('tabpane-perf-bottom-up') export class TabpanePerfBottomUp extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts index dc4aff849..26f793aaa 100644 --- a/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts @@ -13,22 +13,22 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import '../TabPaneFilter.js'; -import { FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { PerfCallChainMerageData, PerfLevelStruct } from '../../../../bean/PerfProfile.js'; -import '../../../chart/FrameChart.js'; -import { FrameChart } from '../../../chart/FrameChart.js'; -import { ChartMode } from '../../../../bean/FrameChartStruct.js'; -import '../../../../../base-ui/slicer/lit-slicer.js'; -import '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { showButtonMenu } from '../SheetUtils.js'; -import '../../../../../base-ui/headline/lit-headline.js'; -import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import '../TabPaneFilter'; +import { FilterData, TabPaneFilter } from '../TabPaneFilter'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { PerfCallChainMerageData, PerfLevelStruct } from '../../../../bean/PerfProfile'; +import '../../../chart/FrameChart'; +import { FrameChart } from '../../../chart/FrameChart'; +import { ChartMode } from '../../../../bean/FrameChartStruct'; +import '../../../../../base-ui/slicer/lit-slicer'; +import '../../../../../base-ui/progress-bar/LitProgressBar'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { procedurePool } from '../../../../database/Procedure'; +import { showButtonMenu } from '../SheetUtils'; +import '../../../../../base-ui/headline/lit-headline'; +import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline'; const InvertOptionIndex: number = 0; const hideThreadOptionIndex: number = 3; diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPerfSampleList.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPerfSampleList.ts index 5cf7de7c8..a1b286985 100644 --- a/ide/src/trace/component/trace/sheet/hiperf/TabPerfSampleList.ts +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPerfSampleList.ts @@ -13,21 +13,21 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { perfDataQuery } from '../../../chart/PerfDataQuery.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { perfDataQuery } from '../../../chart/PerfDataQuery'; import { queryPerfProcess, queryPerfSampleCallChain, queryPerfSampleListByTimeRange, -} from '../../../../database/SqlLite.js'; -import { PerfFile, PerfSample, PerfStack, PerfThread } from '../../../../bean/PerfProfile.js'; -import { Utils } from '../../base/Utils.js'; -import { SpApplication } from '../../../../SpApplication.js'; -import { log } from '../../../../../log/Log.js'; -import '../../../../../base-ui/slicer/lit-slicer.js'; -import { Cmd } from '../../../../../command/Cmd.js'; +} from '../../../../database/SqlLite'; +import { PerfFile, PerfSample, PerfStack, PerfThread } from '../../../../bean/PerfProfile'; +import { Utils } from '../../base/Utils'; +import { SpApplication } from '../../../../SpApplication'; +import { log } from '../../../../../log/Log'; +import '../../../../../base-ui/slicer/lit-slicer'; +import { Cmd } from '../../../../../command/Cmd'; @element('tabpane-perf-sample') export class TabPanePerfSample extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/hisysevent/TabPaneHiSysEventSummary.ts b/ide/src/trace/component/trace/sheet/hisysevent/TabPaneHiSysEventSummary.ts index ef348c5f1..170aec8d4 100644 --- a/ide/src/trace/component/trace/sheet/hisysevent/TabPaneHiSysEventSummary.ts +++ b/ide/src/trace/component/trace/sheet/hisysevent/TabPaneHiSysEventSummary.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { LitIcon } from '../../../../../base-ui/icon/LitIcon.js'; -import { HiSysEventStruct } from '../../../../database/ui-worker/ProcedureWorkerHiSysEvent.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { ColorUtils } from '../../base/ColorUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { LitIcon } from '../../../../../base-ui/icon/LitIcon'; +import { HiSysEventStruct } from '../../../../database/ui-worker/ProcedureWorkerHiSysEvent'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { ColorUtils } from '../../base/ColorUtils'; @element('tab-hi-sysevent-summary') export class TabPaneHiSysEventSummary extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/hisysevent/TabPaneHisysEvents.ts b/ide/src/trace/component/trace/sheet/hisysevent/TabPaneHisysEvents.ts index 6d0e14707..eed0e4b5a 100644 --- a/ide/src/trace/component/trace/sheet/hisysevent/TabPaneHisysEvents.ts +++ b/ide/src/trace/component/trace/sheet/hisysevent/TabPaneHisysEvents.ts @@ -13,19 +13,19 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { HiSysEventStruct } from '../../../../database/ui-worker/ProcedureWorkerHiSysEvent.js'; -import { ns2x, Rect } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { LitPageTable } from '../../../../../base-ui/table/LitPageTable.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { LitSlicerTrack } from '../../../../../base-ui/slicer/lit-slicer.js'; -import { TraceRow } from '../../base/TraceRow.js'; -import { Flag } from '../../timer-shaft/Flag.js'; -import { TraceSheet } from '../../base/TraceSheet.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { ColorUtils } from '../../base/ColorUtils.js'; -import { queryRealTime } from '../../../../database/SqlLite.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { HiSysEventStruct } from '../../../../database/ui-worker/ProcedureWorkerHiSysEvent'; +import { ns2x, Rect } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { LitPageTable } from '../../../../../base-ui/table/LitPageTable'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { LitSlicerTrack } from '../../../../../base-ui/slicer/lit-slicer'; +import { TraceRow } from '../../base/TraceRow'; +import { Flag } from '../../timer-shaft/Flag'; +import { TraceSheet } from '../../base/TraceSheet'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { ColorUtils } from '../../base/ColorUtils'; +import { queryRealTime } from '../../../../database/SqlLite'; @element('tab-hisysevents') export class TabPaneHisysEvents extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/irq/TabPaneIrqCounter.ts b/ide/src/trace/component/trace/sheet/irq/TabPaneIrqCounter.ts index 8b99c6708..df852c3c6 100644 --- a/ide/src/trace/component/trace/sheet/irq/TabPaneIrqCounter.ts +++ b/ide/src/trace/component/trace/sheet/irq/TabPaneIrqCounter.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-irq-counter') export class TabPaneIrqCounter extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/jank/TabPaneFrames.ts b/ide/src/trace/component/trace/sheet/jank/TabPaneFrames.ts index 589618ca3..ab99fd783 100644 --- a/ide/src/trace/component/trace/sheet/jank/TabPaneFrames.ts +++ b/ide/src/trace/component/trace/sheet/jank/TabPaneFrames.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; import { LitTable } from '../../../../../base-ui/table/lit-table'; -import { JankFramesStruct } from '../../../../bean/JankFramesStruct.js'; -import { JanksStruct } from '../../../../bean/JanksStruct.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { JankFramesStruct } from '../../../../bean/JankFramesStruct'; +import { JanksStruct } from '../../../../bean/JanksStruct'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-frames') export class TabPaneFrames extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMCallTree.ts b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMCallTree.ts index d9bf3be9b..45d7358ce 100644 --- a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMCallTree.ts +++ b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMCallTree.ts @@ -13,21 +13,21 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { FrameChart } from '../../../chart/FrameChart.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { ChartMode } from '../../../../bean/FrameChartStruct.js'; -import { FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { FileMerageBean } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem.js'; -import { queryNativeHookSubType, queryNativeHookStatisticSubType } from '../../../../database/SqlLite.js'; -import { ParseExpression } from '../SheetUtils.js'; -import { FilterByAnalysis, NativeMemoryExpression } from '../../../../bean/NativeHook.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import '../../../../../base-ui/headline/lit-headline.js'; -import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { FrameChart } from '../../../chart/FrameChart'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { ChartMode } from '../../../../bean/FrameChartStruct'; +import { FilterData, TabPaneFilter } from '../TabPaneFilter'; +import { procedurePool } from '../../../../database/Procedure'; +import { FileMerageBean } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; +import { queryNativeHookSubType, queryNativeHookStatisticSubType } from '../../../../database/SqlLite'; +import { ParseExpression } from '../SheetUtils'; +import { FilterByAnalysis, NativeMemoryExpression } from '../../../../bean/NativeHook'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import '../../../../../base-ui/headline/lit-headline'; +import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline'; const InvertOpyionIndex: number = 0; const HideSystemSoOptionIndex: number = 1; diff --git a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMSampleList.ts b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMSampleList.ts index 0389bb358..2b155b793 100644 --- a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMSampleList.ts +++ b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMSampleList.ts @@ -13,24 +13,24 @@ * limitations under the License. */ -import '../../../../../base-ui/table/lit-table-column.js'; -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { queryAllHookData, queryNativeHookSnapshotTypes } from '../../../../database/SqlLite.js'; +import '../../../../../base-ui/table/lit-table-column'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { queryAllHookData, queryNativeHookSnapshotTypes } from '../../../../database/SqlLite'; import { NativeHookCallInfo, NativeHookSampleQueryInfo, NativeHookSamplerInfo, NativeMemory, -} from '../../../../bean/NativeHook.js'; -import { Utils } from '../../base/Utils.js'; -import '../TabPaneFilter.js'; -import { FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import '../../../../../base-ui/slicer/lit-slicer.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { formatRealDateMs, getTimeString } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { SpNativeMemoryChart } from '../../../chart/SpNativeMemoryChart.js'; +} from '../../../../bean/NativeHook'; +import { Utils } from '../../base/Utils'; +import '../TabPaneFilter'; +import { FilterData, TabPaneFilter } from '../TabPaneFilter'; +import '../../../../../base-ui/slicer/lit-slicer'; +import { procedurePool } from '../../../../database/Procedure'; +import { formatRealDateMs, getTimeString } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { SpNativeMemoryChart } from '../../../chart/SpNativeMemoryChart'; @element('tabpane-native-sample') export class TabPaneNMSampleList extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMStatisticAnalysis.ts b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMStatisticAnalysis.ts index 13ae181f9..8d02f0ca3 100644 --- a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMStatisticAnalysis.ts +++ b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMStatisticAnalysis.ts @@ -12,21 +12,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie.js'; -import '../../../../../base-ui/chart/pie/LitChartPie.js'; -import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { Utils } from '../../base/Utils.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { procedurePool } from '../../../../database/Procedure.js'; -import { TabPaneFilter } from '../TabPaneFilter.js'; -import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox.js'; -import { initSort } from '../SheetUtils.js'; -import { TabpaneNMCalltree } from './TabPaneNMCallTree.js'; -import { FilterByAnalysis } from '../../../../bean/NativeHook.js'; -import { InitAnalysis } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie'; +import '../../../../../base-ui/chart/pie/LitChartPie'; +import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { Utils } from '../../base/Utils'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { procedurePool } from '../../../../database/Procedure'; +import { TabPaneFilter } from '../TabPaneFilter'; +import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox'; +import { initSort } from '../SheetUtils'; +import { TabpaneNMCalltree } from './TabPaneNMCallTree'; +import { FilterByAnalysis } from '../../../../bean/NativeHook'; +import { InitAnalysis } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; const TYPE_ALLOC_STRING = 'AllocEvent'; const TYPE_MAP_STRING = 'MmapEvent'; diff --git a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMStatstics.ts b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMStatstics.ts index d12c76130..ca3c350d4 100644 --- a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMStatstics.ts +++ b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMStatstics.ts @@ -13,21 +13,21 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; import { queryNativeHookStatistics, queryNativeHookStatisticsMalloc, queryNativeHookStatisticsSubType, -} from '../../../../database/SqlLite.js'; -import { NativeHookMalloc, NativeHookStatisticsTableData } from '../../../../bean/NativeHook.js'; -import { Utils } from '../../base/Utils.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import '../TabProgressBar.js'; -import { SpNativeMemoryChart } from '../../../chart/SpNativeMemoryChart.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { TabPaneNMSampleList } from './TabPaneNMSampleList.js'; +} from '../../../../database/SqlLite'; +import { NativeHookMalloc, NativeHookStatisticsTableData } from '../../../../bean/NativeHook'; +import { Utils } from '../../base/Utils'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import '../TabProgressBar'; +import { SpNativeMemoryChart } from '../../../chart/SpNativeMemoryChart'; +import { resizeObserver } from '../SheetUtils'; +import { TabPaneNMSampleList } from './TabPaneNMSampleList'; import { env } from 'process'; @element('tabpane-native-statistics') diff --git a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMemory.ts b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMemory.ts index e81641dff..7d2e4a1ca 100644 --- a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMemory.ts +++ b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMemory.ts @@ -13,25 +13,25 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type LitPageTable } from '../../../../../base-ui/table/LitPageTable.js'; -import '../../../../../base-ui/table/LitPageTable.js'; -import '../../../../../base-ui/slicer/lit-slicer.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { type NativeMemory, NativeHookCallInfo } from '../../../../bean/NativeHook.js'; -import '../TabPaneFilter.js'; -import { FilterData, TabPaneFilter } from '../TabPaneFilter.js'; -import { TabPaneNMSampleList } from './TabPaneNMSampleList.js'; -import { type LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; -import { procedurePool } from '../../../../database/Procedure.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type LitPageTable } from '../../../../../base-ui/table/LitPageTable'; +import '../../../../../base-ui/table/LitPageTable'; +import '../../../../../base-ui/slicer/lit-slicer'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { type NativeMemory, NativeHookCallInfo } from '../../../../bean/NativeHook'; +import '../TabPaneFilter'; +import { FilterData, TabPaneFilter } from '../TabPaneFilter'; +import { TabPaneNMSampleList } from './TabPaneNMSampleList'; +import { type LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; +import { procedurePool } from '../../../../database/Procedure'; import { formatRealDateMs, getByteWithUnit, getTimeString, -} from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { SpNativeMemoryChart } from '../../../chart/SpNativeMemoryChart.js'; -import { Utils } from '../../base/Utils.js'; +} from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { SpNativeMemoryChart } from '../../../chart/SpNativeMemoryChart'; +import { Utils } from '../../base/Utils'; @element('tabpane-native-memory') export class TabPaneNMemory extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneCounter.ts b/ide/src/trace/component/trace/sheet/process/TabPaneCounter.ts index d1e5efd7f..b3fd81c16 100644 --- a/ide/src/trace/component/trace/sheet/process/TabPaneCounter.ts +++ b/ide/src/trace/component/trace/sheet/process/TabPaneCounter.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { Counter, SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabCounters, getTabVirtualCounters } from '../../../../database/SqlLite.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { Counter, SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabCounters, getTabVirtualCounters } from '../../../../database/SqlLite'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-counter') export class TabPaneCounter extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts b/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts index b0592a5ed..6745fa1b4 100644 --- a/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts +++ b/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabSlices, getTabSlicesAsyncFunc } from '../../../../database/SqlLite.js'; -import { SpAllocations } from '../../../setting/SpAllocations.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { TraceRow } from '../../base/TraceRow.js'; -import { LitSearch } from '../../search/Search.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabSlices, getTabSlicesAsyncFunc } from '../../../../database/SqlLite'; +import { SpAllocations } from '../../../setting/SpAllocations'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { TraceRow } from '../../base/TraceRow'; +import { LitSearch } from '../../search/Search'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-slices') export class TabPaneSlices extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneStartup.ts b/ide/src/trace/component/trace/sheet/process/TabPaneStartup.ts index edaeaba99..31446dc58 100644 --- a/ide/src/trace/component/trace/sheet/process/TabPaneStartup.ts +++ b/ide/src/trace/component/trace/sheet/process/TabPaneStartup.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabStartups } from '../../../../database/SqlLite.js'; -import { log } from '../../../../../log/Log.js'; -import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { AppStartupStruct } from '../../../../database/ui-worker/ProcedureWorkerAppStartup.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabStartups } from '../../../../database/SqlLite'; +import { log } from '../../../../../log/Log'; +import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { resizeObserver } from '../SheetUtils'; +import { AppStartupStruct } from '../../../../database/ui-worker/ProcedureWorkerAppStartup'; interface StartupTreeItem { name: string; diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneStaticInit.ts b/ide/src/trace/component/trace/sheet/process/TabPaneStaticInit.ts index 05cf471be..906a936a2 100644 --- a/ide/src/trace/component/trace/sheet/process/TabPaneStaticInit.ts +++ b/ide/src/trace/component/trace/sheet/process/TabPaneStaticInit.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabStaticInit } from '../../../../database/SqlLite.js'; -import { log } from '../../../../../log/Log.js'; -import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { SoStruct } from '../../../../database/ui-worker/ProcedureWorkerSoInit.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabStaticInit } from '../../../../database/SqlLite'; +import { log } from '../../../../../log/Log'; +import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { resizeObserver } from '../SheetUtils'; +import { SoStruct } from '../../../../database/ui-worker/ProcedureWorkerSoInit'; interface SoTreeItem { name: string; diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneThreadStates.ts b/ide/src/trace/component/trace/sheet/process/TabPaneThreadStates.ts index 4c50e7fa9..06a433cf8 100644 --- a/ide/src/trace/component/trace/sheet/process/TabPaneThreadStates.ts +++ b/ide/src/trace/component/trace/sheet/process/TabPaneThreadStates.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../StackBar.js'; -import { getTabThreadStates, getTabThreadStatesDetail } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { StackBar } from '../../../StackBar.js'; -import { log } from '../../../../../log/Log.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../StackBar'; +import { getTabThreadStates, getTabThreadStatesDetail } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { StackBar } from '../../../StackBar'; +import { log } from '../../../../../log/Log'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-thread-states') export class TabPaneThreadStates extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneThreadUsage.ts b/ide/src/trace/component/trace/sheet/process/TabPaneThreadUsage.ts index d29356984..4a8db661c 100644 --- a/ide/src/trace/component/trace/sheet/process/TabPaneThreadUsage.ts +++ b/ide/src/trace/component/trace/sheet/process/TabPaneThreadUsage.ts @@ -13,16 +13,16 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../StackBar.js'; -import { getTabRunningPersent, getTabThreadStatesCpu } from '../../../../database/SqlLite.js'; -import { log } from '../../../../../log/Log.js'; -import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { Utils } from '../../base/Utils.js'; -import { CpuStruct } from '../../../../database/ui-worker/ProcedureWorkerCPU.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../StackBar'; +import { getTabRunningPersent, getTabThreadStatesCpu } from '../../../../database/SqlLite'; +import { log } from '../../../../../log/Log'; +import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { Utils } from '../../base/Utils'; +import { CpuStruct } from '../../../../database/ui-worker/ProcedureWorkerCPU'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-thread-usage') export class TabPaneThreadUsage extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/sdk/TabPaneSdkCounter.ts b/ide/src/trace/component/trace/sheet/sdk/TabPaneSdkCounter.ts index 109d7d777..030111e9a 100644 --- a/ide/src/trace/component/trace/sheet/sdk/TabPaneSdkCounter.ts +++ b/ide/src/trace/component/trace/sheet/sdk/TabPaneSdkCounter.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabSdkCounterData, getTabSdkCounterLeftData, queryStartTime } from '../../../../database/SqlLite.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabSdkCounterData, getTabSdkCounterLeftData, queryStartTime } from '../../../../database/SqlLite'; import { LitTableColumn } from '../../../../../base-ui/table/lit-table-column'; -import { Utils } from '../../base/Utils.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { TabUtil } from './TabUtil.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { Utils } from '../../base/Utils'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { TabUtil } from './TabUtil'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-sdk-counter') export class TabPaneSdkCounter extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/sdk/TabPaneSdkSlice.ts b/ide/src/trace/component/trace/sheet/sdk/TabPaneSdkSlice.ts index ed5a07277..e2e3371fa 100644 --- a/ide/src/trace/component/trace/sheet/sdk/TabPaneSdkSlice.ts +++ b/ide/src/trace/component/trace/sheet/sdk/TabPaneSdkSlice.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabSdkSliceData, queryStartTime, queryTotalTime } from '../../../../database/SqlLite.js'; -import { LitTableColumn } from '../../../../../base-ui/table/lit-table-column.js'; -import { Utils } from '../../base/Utils.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { TabUtil } from './TabUtil.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabSdkSliceData, queryStartTime, queryTotalTime } from '../../../../database/SqlLite'; +import { LitTableColumn } from '../../../../../base-ui/table/lit-table-column'; +import { Utils } from '../../base/Utils'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { TabUtil } from './TabUtil'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-sdk-slice') export class TabPaneSdkSlice extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsComparison.ts b/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsComparison.ts index 79753f1b1..3ce1ec41f 100644 --- a/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsComparison.ts +++ b/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsComparison.ts @@ -12,16 +12,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { element } from '../../../../../base-ui/BaseElement.js'; -import { type LitSelect } from '../../../../../base-ui/select/LitSelect.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabSmapsStatisticData } from '../../../../database/SqlLite.js'; -import { resizeObserverFromMemory } from '../SheetUtils.js'; -import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; -import { TabPaneSmapsStatistics } from './TabPaneSmapsStatistics.js'; -import { type SmapsType } from '../../../../bean/SmapsStruct.js'; +import { element } from '../../../../../base-ui/BaseElement'; +import { type LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabSmapsStatisticData } from '../../../../database/SqlLite'; +import { resizeObserverFromMemory } from '../SheetUtils'; +import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; +import { TabPaneSmapsStatistics } from './TabPaneSmapsStatistics'; +import { type SmapsType } from '../../../../bean/SmapsStruct'; @element('tabpane-smaps-comparison') export class TabPaneSmapsComparison extends TabPaneSmapsStatistics { diff --git a/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsRecord.ts b/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsRecord.ts index 413368491..78d9471f9 100644 --- a/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsRecord.ts +++ b/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsRecord.ts @@ -13,17 +13,17 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { SmapsType } from '../../../../bean/SmapsStruct.js'; -import { querySmapsRecordTabData } from '../../../../database/SqlLite.js'; -import { getByteWithUnit } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { SmapsType } from '../../../../bean/SmapsStruct'; +import { querySmapsRecordTabData } from '../../../../database/SqlLite'; +import { getByteWithUnit } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-smaps-record') export class TabPaneSmapsRecord extends BaseElement { private smapsRecordTable: LitTable | undefined | null; diff --git a/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsSample.ts b/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsSample.ts index 0adc3f8ae..1dd95e510 100644 --- a/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsSample.ts +++ b/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsSample.ts @@ -12,15 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; -import { getTabSmapsData, getTabSmapsSampleData } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { log } from '../../../../../log/Log.js'; -import { Smaps, SmapsType, TYPE_STRING } from '../../../../bean/SmapsStruct.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; +import { getTabSmapsData, getTabSmapsSampleData } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { log } from '../../../../../log/Log'; +import { Smaps, SmapsType, TYPE_STRING } from '../../../../bean/SmapsStruct'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { SpSystemTrace } from '../../../SpSystemTrace'; @element('tabpane-smaps-sample') export class TabPaneSmapsSample extends BaseElement { private tblSmapsSample: LitTable | null | undefined; diff --git a/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsStatistics.ts b/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsStatistics.ts index 986493bb7..44f7a5769 100644 --- a/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsStatistics.ts +++ b/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsStatistics.ts @@ -12,19 +12,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionParam } from '../../../../bean/BoxSelection.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionParam } from '../../../../bean/BoxSelection'; import { getTabSmapsMaxSize, getTabSmapsStatisticData, getTabSmapsStatisticMaxSize, getTabSmapsStatisticSelectData, -} from '../../../../database/SqlLite.js'; -import { type Smaps, SmapsTreeObj, SmapsType, TYPE_STRING } from '../../../../bean/SmapsStruct.js'; -import { Utils } from '../../base/Utils.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; +} from '../../../../database/SqlLite'; +import { type Smaps, SmapsTreeObj, SmapsType, TYPE_STRING } from '../../../../bean/SmapsStruct'; +import { Utils } from '../../base/Utils'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { SpSystemTrace } from '../../../SpSystemTrace'; @element('tabpane-smaps-statistics') export class TabPaneSmapsStatistics extends BaseElement { private tblSmapsStatistics: LitTable | null | undefined; diff --git a/ide/src/trace/component/trace/sheet/task/TabPaneTaskFrames.ts b/ide/src/trace/component/trace/sheet/task/TabPaneTaskFrames.ts index 7b9bb689d..1d3e7f09b 100644 --- a/ide/src/trace/component/trace/sheet/task/TabPaneTaskFrames.ts +++ b/ide/src/trace/component/trace/sheet/task/TabPaneTaskFrames.ts @@ -13,19 +13,19 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; import { SelectionParam } from '../../../../bean/BoxSelection'; import { LitTable } from '../../../../../base-ui/table/lit-table'; -import { resizeObserver } from '../SheetUtils.js'; -import { FuncStruct } from '../../../../database/ui-worker/ProcedureWorkerFunc.js'; +import { resizeObserver } from '../SheetUtils'; +import { FuncStruct } from '../../../../database/ui-worker/ProcedureWorkerFunc'; import { queryConcurrencyTask, queryTaskListByExecuteTaskIds, queryTaskPoolTotalNum, -} from '../../../../database/SqlLite.js'; -import { BaseStruct } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { type LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js'; +} from '../../../../database/SqlLite'; +import { BaseStruct } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { type LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; const ALLOCATION_TASK = 'H:Task Allocation:'; const PERFORM_TASK = 'H:Task Perform:'; diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaSelectVmTracker.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaSelectVmTracker.ts index ea2fbcbdc..812906df9 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaSelectVmTracker.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaSelectVmTracker.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type Dma } from '../../../../bean/AbilityMonitor.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { getTabDmaVMTrackerClickData } from '../../../../database/SqlLite.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { Utils } from '../../base/Utils.js'; -import { ns2s } from '../../TimerShaftElement.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type Dma } from '../../../../bean/AbilityMonitor'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { getTabDmaVMTrackerClickData } from '../../../../database/SqlLite'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { Utils } from '../../base/Utils'; +import { ns2s } from '../../TimerShaftElement'; @element('tabpane-dma-selection-vmtracker') export class TabPaneDmaSelectVmTracker extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaVmTracker.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaVmTracker.ts index b9cba2946..cf611d231 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaVmTracker.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaVmTracker.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { getTabDmaVmTrackerData } from '../../../../database/SqlLite.js'; -import { type Dma } from '../../../../bean/AbilityMonitor.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { resizeObserver } from '../SheetUtils'; +import { getTabDmaVmTrackerData } from '../../../../database/SqlLite'; +import { type Dma } from '../../../../bean/AbilityMonitor'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { Utils } from '../../base/Utils'; @element('tabpane-dma-vmtracker') export class TabPaneDmaVmTracker extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaVmTrackerComparison.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaVmTrackerComparison.ts index 06f2183e6..b6233f713 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaVmTrackerComparison.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneDmaVmTrackerComparison.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitSelect } from '../../../../../base-ui/select/LitSelect.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type DmaComparison } from '../../../../bean/AbilityMonitor.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { getTabDmaVmTrackerComparisonData } from '../../../../database/SqlLite.js'; -import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot.js'; -import { Utils } from '../../base/Utils.js'; -import { resizeObserverFromMemory } from '../SheetUtils.js'; -import '../TabPaneJsMemoryFilter.js'; -import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type DmaComparison } from '../../../../bean/AbilityMonitor'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { getTabDmaVmTrackerComparisonData } from '../../../../database/SqlLite'; +import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot'; +import { Utils } from '../../base/Utils'; +import { resizeObserverFromMemory } from '../SheetUtils'; +import '../TabPaneJsMemoryFilter'; +import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; @element('tabpane-dma-vmtracker-comparison') export class TabPaneDmaVmTrackerComparison extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemorySelectVmTracker.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemorySelectVmTracker.ts index 13eca83b6..5e9a4f564 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemorySelectVmTracker.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemorySelectVmTracker.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type GpuMemory } from '../../../../bean/AbilityMonitor.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { getTabGpuMemoryVMTrackerClickData } from '../../../../database/SqlLite.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type GpuMemory } from '../../../../bean/AbilityMonitor'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { getTabGpuMemoryVMTrackerClickData } from '../../../../database/SqlLite'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { Utils } from '../../base/Utils'; @element('tabpane-gpu-memory-selection-vmtracker') export class TabPaneGpuMemorySelectVmTracker extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemoryVmTracker.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemoryVmTracker.ts index 646f03966..a3af32e2b 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemoryVmTracker.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemoryVmTracker.ts @@ -13,15 +13,15 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { resizeObserver } from '../SheetUtils.js'; -import { getTabGpuMemoryData } from '../../../../database/SqlLite.js'; -import { GpuMemory } from '../../../../bean/AbilityMonitor.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { Utils } from '../../base/Utils.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { resizeObserver } from '../SheetUtils'; +import { getTabGpuMemoryData } from '../../../../database/SqlLite'; +import { GpuMemory } from '../../../../bean/AbilityMonitor'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { Utils } from '../../base/Utils'; +import { SpSystemTrace } from '../../../SpSystemTrace'; @element('tabpane-gpu-memory-vmtracker') export class TabPaneGpuMemoryVmTracker extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemoryVmTrackerComparison.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemoryVmTrackerComparison.ts index 3606c9de2..ebc9671cd 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemoryVmTrackerComparison.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuMemoryVmTrackerComparison.ts @@ -13,19 +13,19 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitSelect } from '../../../../../base-ui/select/LitSelect.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { GpuMemoryComparison } from '../../../../bean/AbilityMonitor.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { getTabGpuMemoryVmTrackerComparisonData } from '../../../../database/SqlLite.js'; -import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { Utils } from '../../base/Utils.js'; -import { compare, resizeObserverFromMemory } from '../SheetUtils.js'; -import '../TabPaneJsMemoryFilter.js'; -import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { GpuMemoryComparison } from '../../../../bean/AbilityMonitor'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { getTabGpuMemoryVmTrackerComparisonData } from '../../../../database/SqlLite'; +import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { Utils } from '../../base/Utils'; +import { compare, resizeObserverFromMemory } from '../SheetUtils'; +import '../TabPaneJsMemoryFilter'; +import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; @element('tabpane-gpu-memory-vmtracker-comparison') export class TabPaneGpuMemoryVmTrackerComparison extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuResourceVmTracker.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuResourceVmTracker.ts index 1dd1fcd91..6677de145 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuResourceVmTracker.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneGpuResourceVmTracker.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { queryGpuResourceTabData } from '../../../../database/SqlLite.js'; -import { getByteWithUnit } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { resizeObserver } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { queryGpuResourceTabData } from '../../../../database/SqlLite'; +import { getByteWithUnit } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { resizeObserver } from '../SheetUtils'; @element('tabpane-gpu-resource') export class TabPaneGpuResourceVmTracker extends BaseElement { private gpuResourceTable: LitTable | undefined | null; diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPanePurgPinComparisonVM.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPanePurgPinComparisonVM.ts index 68295a39f..3f8a883f9 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPanePurgPinComparisonVM.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPanePurgPinComparisonVM.ts @@ -12,16 +12,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type LitSelect } from '../../../../../base-ui/select/LitSelect.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { queryProcessPurgeableSelectionTab } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { CompareStruct, compare, resizeObserverFromMemory } from '../SheetUtils.js'; -import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { queryProcessPurgeableSelectionTab } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { CompareStruct, compare, resizeObserverFromMemory } from '../SheetUtils'; +import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; @element('tabpane-purgeable-pin-comparison-vm') export class TabPanePurgPinComparisonVM extends BaseElement { private purgeablePinTable: LitTable | null | undefined; diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPanePurgTotalComparisonVM.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPanePurgTotalComparisonVM.ts index c7b1d52d0..6c9d7254d 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPanePurgTotalComparisonVM.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPanePurgTotalComparisonVM.ts @@ -12,16 +12,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitSelect } from '../../../../../base-ui/select/LitSelect.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { type SelectionParam } from '../../../../bean/BoxSelection.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { queryProcessPurgeableSelectionTab } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { CompareStruct, compare, resizeObserverFromMemory } from '../SheetUtils.js'; -import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { type SelectionParam } from '../../../../bean/BoxSelection'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { queryProcessPurgeableSelectionTab } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { CompareStruct, compare, resizeObserverFromMemory } from '../SheetUtils'; +import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; @element('tabpane-purgeable-total-comparison-vm') export class TabPanePurgTotalComparisonVM extends BaseElement { private purgeableTotalTable: LitTable | null | undefined; diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShm.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShm.ts index b0480c539..ec647f6da 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShm.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShm.ts @@ -12,13 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; import { type SelectionParam } from '../../../../bean/BoxSelection'; -import { queryVmTrackerShmSizeData } from '../../../../database/SqlLite.js'; -import { Utils } from '../../base/Utils.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; +import { queryVmTrackerShmSizeData } from '../../../../database/SqlLite'; +import { Utils } from '../../base/Utils'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; @element('tabpane-vmtracker-shm') export class TabPaneVmTrackerShm extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShmComparison.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShmComparison.ts index a5f233bfd..18ebc9681 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShmComparison.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShmComparison.ts @@ -12,17 +12,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { type LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { queryVmTrackerShmSelectionData } from '../../../../database/SqlLite.js'; -import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot.js'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; -import { Utils } from '../../base/Utils.js'; -import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js'; -import { type LitSelect } from '../../../../../base-ui/select/LitSelect.js'; -import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js'; -import { resizeObserverFromMemory } from '../SheetUtils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { type LitTable } from '../../../../../base-ui/table/lit-table'; +import { queryVmTrackerShmSelectionData } from '../../../../database/SqlLite'; +import { type SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; +import { Utils } from '../../base/Utils'; +import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; +import { type LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; +import { resizeObserverFromMemory } from '../SheetUtils'; @element('tabpane-vmtracker-shm-comparison') export class TabPaneVmTrackerShmComparison extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShmSelection.ts b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShmSelection.ts index 6eb48eb5f..03b2c464d 100644 --- a/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShmSelection.ts +++ b/ide/src/trace/component/trace/sheet/vmtracker/TabPaneVmTrackerShmSelection.ts @@ -12,14 +12,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../../base-ui/table/lit-table.js'; -import { queryVmTrackerShmSelectionData } from '../../../../database/SqlLite.js'; -import { SpSystemTrace } from '../../../SpSystemTrace.js'; -import { Utils } from '../../base/Utils.js'; +import { BaseElement, element } from '../../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { queryVmTrackerShmSelectionData } from '../../../../database/SqlLite'; +import { SpSystemTrace } from '../../../SpSystemTrace'; +import { Utils } from '../../base/Utils'; import { SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot'; -import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; -import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; +import { MemoryConfig } from '../../../../bean/MemoryConfig'; +import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; @element('tabpane-vmtracker-shm-selection') export class TabPaneVmTrackerShmSelection extends BaseElement { diff --git a/ide/src/trace/component/trace/timer-shaft/CollapseButton.ts b/ide/src/trace/component/trace/timer-shaft/CollapseButton.ts index 25b74d338..27e0fb8d2 100644 --- a/ide/src/trace/component/trace/timer-shaft/CollapseButton.ts +++ b/ide/src/trace/component/trace/timer-shaft/CollapseButton.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; -import '../../../../base-ui/BaseElement.js'; -import '../../../../base-ui/icon/LitIcon.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; +import '../../../../base-ui/BaseElement'; +import '../../../../base-ui/icon/LitIcon'; @element('collapse-button') export default class CollapseButton extends BaseElement { diff --git a/ide/src/trace/component/trace/timer-shaft/Graph.ts b/ide/src/trace/component/trace/timer-shaft/Graph.ts index 7117194ce..9137b07df 100644 --- a/ide/src/trace/component/trace/timer-shaft/Graph.ts +++ b/ide/src/trace/component/trace/timer-shaft/Graph.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { Rect } from './Rect.js'; +import { Rect } from './Rect'; export abstract class Graph { frame: Rect; diff --git a/ide/src/trace/component/trace/timer-shaft/RangeRuler.ts b/ide/src/trace/component/trace/timer-shaft/RangeRuler.ts index e3b13bcdc..78af1d9af 100644 --- a/ide/src/trace/component/trace/timer-shaft/RangeRuler.ts +++ b/ide/src/trace/component/trace/timer-shaft/RangeRuler.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { Graph } from './Graph.js'; -import { Rect } from './Rect.js'; -import { ns2s, ns2UnitS, TimerShaftElement } from '../TimerShaftElement.js'; -import { ColorUtils, interpolateColorBrightness } from '../base/ColorUtils.js'; -import { CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU.js'; -import { CurrentSlicesTime, SpSystemTrace } from '../../SpSystemTrace.js'; +import { Graph } from './Graph'; +import { Rect } from './Rect'; +import { ns2s, ns2UnitS, TimerShaftElement } from '../TimerShaftElement'; +import { ColorUtils, interpolateColorBrightness } from '../base/ColorUtils'; +import { CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU'; +import { CurrentSlicesTime, SpSystemTrace } from '../../SpSystemTrace'; const MarkPadding = 5; const FIT_TOTALX_MIN: number = 280; @@ -412,17 +412,17 @@ export class RangeRuler extends Graph { this.animaStartTime = dat.getTime(); } this.currentDuration = new Date().getTime() - this.animaStartTime; - this.setCacheInterval(); - this.range.refresh = this.cacheInterval.flag; + this.setCacheInterval(new Date().getTime() - this.animaStartTime); } - setCacheInterval() { - if (Math.trunc(this.currentDuration / this.cacheInterval.interval) !== this.cacheInterval.value) { + setCacheInterval(offsetTime:number) { + if (Math.trunc(offsetTime / this.cacheInterval.interval) !== this.cacheInterval.value) { this.cacheInterval.flag = true; - this.cacheInterval.value = Math.trunc(this.currentDuration / this.cacheInterval.interval); + this.cacheInterval.value = Math.trunc(offsetTime / this.cacheInterval.interval); } else { this.cacheInterval.flag = false; } + this.range.refresh = this.cacheInterval.flag; } delayDraw() { @@ -481,49 +481,21 @@ export class RangeRuler extends Graph { } cancelTimeOut: any = undefined; + isKeyPress: boolean = false; keyPress(keyboardEvent: KeyboardEvent, currentSlicesTime?: CurrentSlicesTime) { - if (currentSlicesTime) { - this.currentSlicesTime = currentSlicesTime; - } - if ( - this.animaStartTime == undefined || - (this.pressedKeys.length > 0 && - this.pressedKeys[this.pressedKeys.length - 1] !== keyboardEvent.key.toLocaleLowerCase()) - ) { - let dat = new Date(); - dat.setTime(dat.getTime() - 400); - this.animaStartTime = dat.getTime(); - } - this.currentDuration = new Date().getTime() - this.animaStartTime; - this.setCacheInterval(); - this.range.refresh = this.cacheInterval.flag; - if (this.pressedKeys.length > 0) { - if (this.pressedKeys[this.pressedKeys.length - 1] !== keyboardEvent.key.toLocaleLowerCase()) { - this.cancelPressFrame(); - this.cancelUpFrame(); - this.pressedKeys.push(keyboardEvent.key.toLocaleLowerCase()); - let date = new Date(); - date.setTime(date.getTime() - 400); - this.animaStartTime = date.getTime(); - this.keyboardKeyPressMap[this.pressedKeys[this.pressedKeys.length - 1]]?.bind(this)(); + //第一个按键或者最后一个按下的和当前按键不一致 + if (this.pressedKeys.length == 0 || this.pressedKeys[this.pressedKeys.length - 1] !== keyboardEvent.key.toLocaleLowerCase()) { + if (currentSlicesTime) { + this.currentSlicesTime = currentSlicesTime; } - } else { this.cancelPressFrame(); this.cancelUpFrame(); this.pressedKeys.push(keyboardEvent.key.toLocaleLowerCase()); - let dat = new Date(); - dat.setTime(dat.getTime() - 400); - this.animaStartTime = dat.getTime(); + this.animaStartTime = new Date().getTime();//记录按下的时间 this.keyboardKeyPressMap[this.pressedKeys[this.pressedKeys.length - 1]]?.bind(this)(); } this.isPress = true; - if (this.cancelTimeOut) { - clearTimeout(this.cancelTimeOut); - } - this.cancelTimeOut = setTimeout(() => { - this.keyUp({ key: keyboardEvent.key } as KeyboardEvent); - }, 1000); } keyPressF(): void { @@ -615,11 +587,11 @@ export class RangeRuler extends Graph { x++; if (sliceMidX >= midX - MID_OFFSET && sliceMidX <= midX + MID_OFFSET) { /* 把 endNS 转换为 endX , startNS 转化 startX, - totalX = ( endX - startX ) 280px <= totalX <= 300px - 此时,如果slice的比例或者宽度不合适,则进行调整校正,缩放到合适的比例。 - 不能使用固定的 scale, 因为调整slice的宽度时,scale、 startNS 和 endNS 都在变化, - 所以要使用 totalX 来判断slice是否缩放到合适的大小了。 - */ + totalX = ( endX - startX ) 280px <= totalX <= 300px + 此时,如果slice的比例或者宽度不合适,则进行调整校正,缩放到合适的比例。 + 不能使用固定的 scale, 因为调整slice的宽度时,scale、 startNS 和 endNS 都在变化, + 所以要使用 totalX 来判断slice是否缩放到合适的大小了。 + */ if ( (totalX < FIT_TOTALX_MIN - MID_OFFSET && totalX > 0) || Math.round(totalX) > FIT_TOTALX_MAX + MID_OFFSET @@ -709,8 +681,13 @@ export class RangeRuler extends Graph { this.pressFrameIdF = requestAnimationFrame(animF); this.zoomFit(startTime, endTime); } + + fixReg = 76;//速度上线 + f = 11;//加速度系数,值越小加速度越大 keyPressW() { let animW = () => { + let offset = Date.now() - this.animaStartTime!; + this.setCacheInterval(offset); if (this.scale === 50) { this.fillX(); this.range.refresh = true; @@ -718,8 +695,11 @@ export class RangeRuler extends Graph { this.range.refresh = false; return; } - this.range.startNS += (this.centerXPercentage * this.currentDuration * this.scale) / this.p; - this.range.endNS -= ((1 - this.centerXPercentage) * this.currentDuration * this.scale) / this.p; + this.currentDuration = (offset) / this.f;//reg + if (this.currentDuration >= this.fixReg) this.currentDuration = this.fixReg; + let bb = Math.tan(Math.PI / 180 * this.currentDuration); + this.range.startNS += (this.centerXPercentage * bb * this.scale); + this.range.endNS -= ((1 - this.centerXPercentage) * bb * this.scale); this.fillX(); this.draw(); this.range.refresh = false; @@ -730,6 +710,8 @@ export class RangeRuler extends Graph { keyPressS() { let animS = () => { + let offset = Date.now() - this.animaStartTime!; + this.setCacheInterval(offset); if (this.range.startNS <= 0 && this.range.endNS >= this.range.totalNS) { this.fillX(); this.range.refresh = true; @@ -737,8 +719,11 @@ export class RangeRuler extends Graph { this.range.refresh = false; return; } - this.range.startNS -= ((this.centerXPercentage * this.scale) / this.p) * this.currentDuration; - this.range.endNS += (((1 - this.centerXPercentage) * this.scale) / this.p) * this.currentDuration; + this.currentDuration = (offset) / this.f + if (this.currentDuration >= this.fixReg) this.currentDuration = this.fixReg; + let bb = Math.tan(Math.PI / 180 * this.currentDuration); + this.range.startNS -= ((this.centerXPercentage * bb * this.scale)); + this.range.endNS += (((1 - this.centerXPercentage) * bb * this.scale)); this.fillX(); this.draw(); this.range.refresh = false; @@ -749,6 +734,8 @@ export class RangeRuler extends Graph { keyPressA() { let animA = () => { + let offset = Date.now() - this.animaStartTime!; + this.setCacheInterval(offset); if (this.range.startNS <= 0) { this.fillX(); this.range.refresh = true; @@ -756,7 +743,10 @@ export class RangeRuler extends Graph { this.range.refresh = false; return; } - let s = (this.scale / this.p) * this.currentDuration * 0.4; + this.currentDuration = (offset) / this.f + if (this.currentDuration >= this.fixReg) this.currentDuration = this.fixReg; + let bb = Math.tan(Math.PI / 180 * this.currentDuration); + let s = this.scale * bb; this.range.startNS -= s; this.range.endNS -= s; this.fillX(); @@ -769,6 +759,8 @@ export class RangeRuler extends Graph { keyPressD() { let animD = () => { + let offset = Date.now() - this.animaStartTime!; + this.setCacheInterval(offset); if (this.range.endNS >= this.range.totalNS) { this.fillX(); this.range.refresh = true; @@ -776,7 +768,10 @@ export class RangeRuler extends Graph { this.range.refresh = false; return; } - let s = (this.scale / this.p) * this.currentDuration * 0.4; + this.currentDuration = (offset) / this.f + if (this.currentDuration >= this.fixReg) this.currentDuration = this.fixReg; + let bb = Math.tan(Math.PI / 180 * this.currentDuration); + let s = this.scale * bb; this.range.startNS += s; this.range.endNS += s; this.fillX(); @@ -823,23 +818,21 @@ export class RangeRuler extends Graph { let animW = () => { if (this.scale === 50) { this.fillX(); - this.range.refresh = true; - this.notifyHandler(this.range); - this.range.refresh = false; + this.keyUpEnd(); return; } let dur = new Date().getTime() - startTime; - this.range.startNS += (this.centerXPercentage * 100 * this.scale) / this.p; - this.range.endNS -= ((1 - this.centerXPercentage) * 100 * this.scale) / this.p; + if (dur > 150) dur = 150; + let offset = Math.tan(Math.PI / 180 * (150 - dur) * 0.2) * this.scale; + this.range.startNS += (this.centerXPercentage * offset); + this.range.endNS -= ((1 - this.centerXPercentage) * offset); this.fillX(); this.draw(); this.range.refresh = false; - if (dur < 100) { + if (dur < 150) { this.upFrameIdW = requestAnimationFrame(animW); } else { - this.range.refresh = true; - this.notifyHandler(this.range); - this.range.refresh = false; + this.keyUpEnd(); } }; this.upFrameIdW = requestAnimationFrame(animW); @@ -850,23 +843,21 @@ export class RangeRuler extends Graph { let animS = () => { if (this.range.startNS <= 0 && this.range.endNS >= this.range.totalNS) { this.fillX(); - this.range.refresh = true; - this.notifyHandler(this.range); - this.range.refresh = false; + this.keyUpEnd(); return; } let dur = new Date().getTime() - startTime; - this.range.startNS -= (this.centerXPercentage * 100 * this.scale) / this.p; - this.range.endNS += ((1 - this.centerXPercentage) * 100 * this.scale) / this.p; + if (dur > 150) dur = 150; + let offset = Math.tan(Math.PI / 180 * (150 - dur) * 0.2) * this.scale; + this.range.startNS -= (this.centerXPercentage * offset); + this.range.endNS += ((1 - this.centerXPercentage) * offset); this.fillX(); this.draw(); this.range.refresh = false; - if (dur < 100) { + if (dur < 150) { this.upFrameIdS = requestAnimationFrame(animS); } else { - this.range.refresh = true; - this.notifyHandler(this.range); - this.range.refresh = false; + this.keyUpEnd(); } }; this.upFrameIdS = requestAnimationFrame(animS); @@ -877,51 +868,52 @@ export class RangeRuler extends Graph { let animA = () => { if (this.range.startNS <= 0) { this.fillX(); - this.range.refresh = true; - this.notifyHandler(this.range); - this.range.refresh = false; + this.keyUpEnd(); return; } let dur = new Date().getTime() - startTime; - let s = (this.scale * 80) / this.p; - this.range.startNS -= s; - this.range.endNS -= s; + if (dur > 150) dur = 150; + let offset = Math.tan(Math.PI / 180 * (150 - dur) * 0.15) * this.scale; + this.range.startNS -= offset; + this.range.endNS -= offset; this.fillX(); this.draw(); this.range.refresh = false; - if (dur < 100) { + if (dur < 150) { this.upFrameIdA = requestAnimationFrame(animA); } else { - this.range.refresh = true; - this.notifyHandler(this.range); - this.range.refresh = false; + this.keyUpEnd(); } }; this.upFrameIdA = requestAnimationFrame(animA); } + keyUpEnd() { + this.range.refresh = true; + // window.isLastFrame = true; + this.notifyHandler(this.range); + this.range.refresh = false; + // window.isLastFrame = false; + } + keyUpD(): void { let startTime = new Date().getTime(); let animD = () => { if (this.range.endNS >= this.range.totalNS) { - this.range.refresh = true; - this.notifyHandler(this.range); - this.range.refresh = false; + this.keyUpEnd(); return; } let dur = new Date().getTime() - startTime; - let s = (this.scale * 80) / this.p; - this.range.startNS += s; - this.range.endNS += s; + let offset = Math.tan(Math.PI / 180 * (150 - dur) * 0.15) * this.scale; + this.range.startNS += offset; + this.range.endNS += offset; this.fillX(); this.draw(); this.range.refresh = false; - if (dur < 100) { + if (dur < 150) { this.upFrameIdD = requestAnimationFrame(animD); } else { - this.range.refresh = true; - this.notifyHandler(this.range); - this.range.refresh = false; + this.keyUpEnd(); } }; this.upFrameIdD = requestAnimationFrame(animD); diff --git a/ide/src/trace/component/trace/timer-shaft/SportRuler.ts b/ide/src/trace/component/trace/timer-shaft/SportRuler.ts index 91eb01ff6..b40342fb5 100644 --- a/ide/src/trace/component/trace/timer-shaft/SportRuler.ts +++ b/ide/src/trace/component/trace/timer-shaft/SportRuler.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { Graph } from './Graph.js'; -import { Rect } from './Rect.js'; -import { TimeRange } from './RangeRuler.js'; -import { Flag } from './Flag.js'; -import { ns2s, ns2x, randomRgbColor, TimerShaftElement } from '../TimerShaftElement.js'; -import { TraceRow } from '../base/TraceRow.js'; -import { SpApplication } from '../../../SpApplication.js'; -import { Utils } from '../base/Utils.js'; +import { Graph } from './Graph'; +import { Rect } from './Rect'; +import { TimeRange } from './RangeRuler'; +import { Flag } from './Flag'; +import { ns2s, ns2x, randomRgbColor, TimerShaftElement } from '../TimerShaftElement'; +import { TraceRow } from '../base/TraceRow'; +import { SpApplication } from '../../../SpApplication'; +import { Utils } from '../base/Utils'; export enum StType { TEMP, //临时的 diff --git a/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts b/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts index 976bccf21..b0d3a668f 100644 --- a/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts +++ b/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts @@ -13,13 +13,13 @@ * limitations under the License. */ -import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; -import { LitTable } from '../../../../base-ui/table/lit-table.js'; -import { MarkStruct } from '../../../bean/MarkStruct.js'; -import { SpSystemTrace } from '../../SpSystemTrace.js'; -import { ns2s } from '../TimerShaftElement.js'; -import { getTimeString } from '../sheet/TabPaneCurrentSelection.js'; -import { Flag } from './Flag.js'; +import { BaseElement, element } from '../../../../base-ui/BaseElement'; +import { LitTable } from '../../../../base-ui/table/lit-table'; +import { MarkStruct } from '../../../bean/MarkStruct'; +import { SpSystemTrace } from '../../SpSystemTrace'; +import { ns2s } from '../TimerShaftElement'; +import { getTimeString } from '../sheet/TabPaneCurrentSelection'; +import { Flag } from './Flag'; @element('tabpane-flag') export class TabPaneFlag extends BaseElement { diff --git a/ide/src/trace/component/trace/timer-shaft/TimeRuler.ts b/ide/src/trace/component/trace/timer-shaft/TimeRuler.ts index a802f4f8e..e5f274d82 100644 --- a/ide/src/trace/component/trace/timer-shaft/TimeRuler.ts +++ b/ide/src/trace/component/trace/timer-shaft/TimeRuler.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { Graph } from './Graph.js'; -import { Rect } from './Rect.js'; -import { ns2s, TimerShaftElement } from '../TimerShaftElement.js'; +import { Graph } from './Graph'; +import { Rect } from './Rect'; +import { ns2s, TimerShaftElement } from '../TimerShaftElement'; export class TimeRuler extends Graph { totalNS: number; diff --git a/ide/src/trace/config/customTempConfig.json b/ide/src/trace/config/customTempConfig.json index dc74211f6..ad4fceafb 100644 --- a/ide/src/trace/config/customTempConfig.json +++ b/ide/src/trace/config/customTempConfig.json @@ -1,3 +1,4 @@ + { "subsystems": [ { diff --git a/ide/src/trace/database/Convert.ts b/ide/src/trace/database/Convert.ts index 1698e33fa..72410531e 100644 --- a/ide/src/trace/database/Convert.ts +++ b/ide/src/trace/database/Convert.ts @@ -13,15 +13,17 @@ * limitations under the License. */ -import { DbPool } from './SqlLite.js'; - -class ConvertThread extends Worker { +import { DbPool } from './SqlLite'; +class ConvertThread { busy: boolean = false; isCancelled: boolean = false; id: number = -1; taskMap: any = {}; name: string | undefined; - + worker?:Worker; + constructor(worker:Worker) { + this.worker = worker; + } uuid(): string { // @ts-ignore return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => @@ -42,7 +44,7 @@ class ConvertThread extends Worker { buffer: DbPool.sharedBuffer!, }; try { - this.postMessage(pam, [DbPool.sharedBuffer!]); + this.worker!.postMessage(pam, [DbPool.sharedBuffer!]); } catch (e: any) {} } } @@ -62,9 +64,9 @@ class ConvertPool { for (let i = 0; i < this.maxThreadNumber; i++) { let thread: ConvertThread; if (type === 'convert') { - thread = new ConvertThread('trace/database/ConvertTraceWorker.js'); + thread = new ConvertThread(new Worker(new URL('./ConvertTraceWorker',import.meta.url))); } - thread!.onmessage = (event: MessageEvent) => { + thread!.worker!.onmessage = (event: MessageEvent) => { thread.busy = false; ConvertPool.data = event.data.results; if (Reflect.has(thread.taskMap, event.data.id)) { @@ -83,8 +85,8 @@ class ConvertPool { } } }; - thread!.onmessageerror = (e) => {}; - thread!.onerror = (e) => {}; + thread!.worker!.onmessageerror = (e) => {}; + thread!.worker!.onerror = (e) => {}; thread!.id = i; thread!.busy = false; this.works?.push(thread!); @@ -94,7 +96,7 @@ class ConvertPool { close = () => { for (let i = 0; i < this.works.length; i++) { let thread = this.works[i]; - thread.terminate(); + thread.worker!.terminate(); } this.works.length = 0; }; diff --git a/ide/src/trace/database/DBUtils.ts b/ide/src/trace/database/DBUtils.ts index 79e94b379..674f7a4f6 100644 --- a/ide/src/trace/database/DBUtils.ts +++ b/ide/src/trace/database/DBUtils.ts @@ -1,4 +1,4 @@ -import { info } from '../../log/Log.js'; +import { info } from '../../log/Log'; /** * 数据缓存期限 diff --git a/ide/src/trace/database/LongTraceDBUtils.ts b/ide/src/trace/database/LongTraceDBUtils.ts index 3ca765782..89a5bded1 100644 --- a/ide/src/trace/database/LongTraceDBUtils.ts +++ b/ide/src/trace/database/LongTraceDBUtils.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { IndexedDBHelp } from './IndexedDBHelp.js'; +import { IndexedDBHelp } from './IndexedDBHelp'; export class LongTraceDBUtils { public static instance: LongTraceDBUtils | undefined; diff --git a/ide/src/trace/database/Procedure.ts b/ide/src/trace/database/Procedure.ts index 680f3329f..2809daf2f 100644 --- a/ide/src/trace/database/Procedure.ts +++ b/ide/src/trace/database/Procedure.ts @@ -13,14 +13,19 @@ * limitations under the License. */ -import { query } from './SqlLite.js'; +import { query } from './SqlLite'; -class ProcedureThread extends Worker { +class ProcedureThread{ busy: boolean = false; isCancelled: boolean = false; id: number = -1; taskMap: any = {}; name: string | undefined; + worker?:Worker; + + constructor(worker:Worker) { + this.worker = worker; + } uuid(): string { // @ts-ignore @@ -42,22 +47,22 @@ class ProcedureThread extends Worker { try { if (Array.isArray(transfer)) { if (transfer.length > 0) { - this.postMessage(pam, [...transfer]); + this.worker!.postMessage(pam, [...transfer]); } else { - this.postMessage(pam); + this.worker!.postMessage(pam); } } else { - this.postMessage(pam, [transfer]); + this.worker!.postMessage(pam, [transfer]); } } catch (e: any) {} } else { - this.postMessage(pam); + this.worker!.postMessage(pam); } } cancel() { this.isCancelled = true; - this.terminate(); + this.worker!.terminate(); } } @@ -98,11 +103,11 @@ class ProcedurePool { if (window.useWb) { return; } - let newThread: ProcedureThread = new ProcedureThread('trace/database/ui-worker/ProcedureWorker.js', { + let newThread: ProcedureThread = new ProcedureThread(new Worker(new URL('./ui-worker/ProcedureWorker',import.meta.url), { type: 'module', - }); + })); newThread.name = this.names[this.works.length]; - newThread.onmessage = (event: MessageEvent) => { + newThread.worker!.onmessage = (event: MessageEvent) => { newThread.busy = false; if ((event.data.type as string) == 'timeline-range-changed') { this.timelineChange && this.timelineChange(event.data.results); @@ -122,8 +127,8 @@ class ProcedurePool { this.onComplete(); } }; - newThread.onmessageerror = (e) => {}; - newThread.onerror = (e) => {}; + newThread.worker!.onmessageerror = (e) => {}; + newThread.worker!.onerror = (e) => {}; newThread.id = this.works.length; newThread.busy = false; this.works?.push(newThread); @@ -135,15 +140,15 @@ class ProcedurePool { if (window.useWb) { return; } - let thread: ProcedureThread = new ProcedureThread('trace/database/logic-worker/ProcedureLogicWorker.js', { + let thread: ProcedureThread = new ProcedureThread(new Worker(new URL('./logic-worker/ProcedureLogicWorker',import.meta.url), { type: 'module', - }); + })); thread.name = this.logicDataHandles[this.works.length - this.names.length]; - thread.onmessage = (event: MessageEvent) => { + thread.worker!.onmessage = (event: MessageEvent) => { thread.busy = false; if (event.data.isQuery) { query(event.data.type, event.data.sql, event.data.args, 'exec-buf').then((res: any) => { - thread.postMessage({ + thread.worker!.postMessage({ type: event.data.type, params: { list: res, @@ -177,8 +182,8 @@ class ProcedurePool { this.onComplete(); } }; - thread.onmessageerror = (e) => {}; - thread.onerror = (e) => {}; + thread.worker!.onmessageerror = (e) => {}; + thread.worker!.onerror = (e) => {}; thread.id = this.works.length; thread.busy = false; this.works?.push(thread); @@ -188,7 +193,7 @@ class ProcedurePool { close = () => { for (let i = 0; i < this.works.length; i++) { let thread = this.works[i]; - thread.terminate(); + thread.worker!.terminate(); } this.works.length = 0; }; diff --git a/ide/src/trace/database/SqlLite.ts b/ide/src/trace/database/SqlLite.ts index 354e6384a..d9060747c 100644 --- a/ide/src/trace/database/SqlLite.ts +++ b/ide/src/trace/database/SqlLite.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { Counter, Fps, SelectionData } from '../bean/BoxSelection.js'; -import { WakeupBean } from '../bean/WakeupBean.js'; -import { BinderArgBean } from '../bean/BinderArgBean.js'; -import { SPTChild } from '../bean/StateProcessThread.js'; -import { CpuUsage, Freq } from '../bean/CpuUsage.js'; +import { Counter, Fps, SelectionData } from '../bean/BoxSelection'; +import { WakeupBean } from '../bean/WakeupBean'; +import { BinderArgBean } from '../bean/BinderArgBean'; +import { SPTChild } from '../bean/StateProcessThread'; +import { CpuUsage, Freq } from '../bean/CpuUsage'; import { NativeEvent, @@ -26,7 +26,7 @@ import { NativeHookProcess, NativeHookSampleQueryInfo, NativeHookStatistics, -} from '../bean/NativeHook.js'; +} from '../bean/NativeHook'; import { Dma, DmaComparison, @@ -37,7 +37,7 @@ import { SystemCpuSummary, SystemDiskIOSummary, SystemNetworkSummary, -} from '../bean/AbilityMonitor.js'; +} from '../bean/AbilityMonitor'; import { PerfCall, @@ -47,29 +47,29 @@ import { PerfSample, PerfStack, PerfThread, -} from '../bean/PerfProfile.js'; -import { SearchFuncBean } from '../bean/SearchFuncBean.js'; -import { CounterSummary, SdkSliceSummary } from '../bean/SdkSummary.js'; -import { Smaps } from '../bean/SmapsStruct.js'; -import { CpuFreqRowLimit } from '../component/chart/SpFreqChart.js'; -import { CpuFreqLimitsStruct } from './ui-worker/ProcedureWorkerCpuFreqLimits.js'; -import { CpuStruct } from './ui-worker/ProcedureWorkerCPU.js'; -import { CpuFreqStruct } from './ui-worker/ProcedureWorkerFreq.js'; -import { ThreadStruct } from './ui-worker/ProcedureWorkerThread.js'; -import { FuncStruct } from './ui-worker/ProcedureWorkerFunc.js'; -import { ProcessMemStruct } from './ui-worker/ProcedureWorkerMem.js'; -import { FpsStruct } from './ui-worker/ProcedureWorkerFPS.js'; -import { CpuAbilityMonitorStruct } from './ui-worker/ProcedureWorkerCpuAbility.js'; -import { MemoryAbilityMonitorStruct } from './ui-worker/ProcedureWorkerMemoryAbility.js'; -import { DiskAbilityMonitorStruct } from './ui-worker/ProcedureWorkerDiskIoAbility.js'; -import { NetworkAbilityMonitorStruct } from './ui-worker/ProcedureWorkerNetworkAbility.js'; -import { EnergyAnomalyStruct } from './ui-worker/ProcedureWorkerEnergyAnomaly.js'; -import { EnergyStateStruct } from './ui-worker/ProcedureWorkerEnergyState.js'; -import { CounterStruct } from './ui-worker/ProduceWorkerSdkCounter.js'; -import { SdkSliceStruct } from './ui-worker/ProduceWorkerSdkSlice.js'; -import { SystemDetailsEnergy } from '../bean/EnergyStruct.js'; -import { ClockStruct } from './ui-worker/ProcedureWorkerClock.js'; -import { IrqStruct } from './ui-worker/ProcedureWorkerIrq.js'; +} from '../bean/PerfProfile'; +import { SearchFuncBean } from '../bean/SearchFuncBean'; +import { CounterSummary, SdkSliceSummary } from '../bean/SdkSummary'; +import { Smaps } from '../bean/SmapsStruct'; +import { CpuFreqRowLimit } from '../component/chart/SpFreqChart'; +import { CpuFreqLimitsStruct } from './ui-worker/ProcedureWorkerCpuFreqLimits'; +import { CpuStruct } from './ui-worker/ProcedureWorkerCPU'; +import { CpuFreqStruct } from './ui-worker/ProcedureWorkerFreq'; +import { ThreadStruct } from './ui-worker/ProcedureWorkerThread'; +import { FuncStruct } from './ui-worker/ProcedureWorkerFunc'; +import { ProcessMemStruct } from './ui-worker/ProcedureWorkerMem'; +import { FpsStruct } from './ui-worker/ProcedureWorkerFPS'; +import { CpuAbilityMonitorStruct } from './ui-worker/ProcedureWorkerCpuAbility'; +import { MemoryAbilityMonitorStruct } from './ui-worker/ProcedureWorkerMemoryAbility'; +import { DiskAbilityMonitorStruct } from './ui-worker/ProcedureWorkerDiskIoAbility'; +import { NetworkAbilityMonitorStruct } from './ui-worker/ProcedureWorkerNetworkAbility'; +import { EnergyAnomalyStruct } from './ui-worker/ProcedureWorkerEnergyAnomaly'; +import { EnergyStateStruct } from './ui-worker/ProcedureWorkerEnergyState'; +import { CounterStruct } from './ui-worker/ProduceWorkerSdkCounter'; +import { SdkSliceStruct } from './ui-worker/ProduceWorkerSdkSlice'; +import { SystemDetailsEnergy } from '../bean/EnergyStruct'; +import { ClockStruct } from './ui-worker/ProcedureWorkerClock'; +import { IrqStruct } from './ui-worker/ProcedureWorkerIrq'; import { HeapEdge, HeapLocation, @@ -77,23 +77,26 @@ import { HeapSample, HeapTraceFunctionInfo, } from '../../js-heap/model/DatabaseStruct'; -import { FileInfo } from '../../js-heap/model/UiStruct.js'; -import { AppStartupStruct } from './ui-worker/ProcedureWorkerAppStartup.js'; -import { SoStruct } from './ui-worker/ProcedureWorkerSoInit.js'; -import { HeapTreeDataBean } from './logic-worker/ProcedureLogicWorkerCommon.js'; -import { TaskTabStruct } from '../component/trace/sheet/task/TabPaneTaskFrames.js'; -import { type DeviceStruct } from '../bean/FrameComponentBean.js'; -import { type FrameSpacingStruct } from './ui-worker/ProcedureWorkerFrameSpacing.js'; -import { type FrameDynamicStruct } from './ui-worker/ProcedureWorkerFrameDynamic.js'; -import { type FrameAnimationStruct } from './ui-worker/ProcedureWorkerFrameAnimation.js'; -import { type SnapshotStruct } from './ui-worker/ProcedureWorkerSnapshot.js'; -import { type MemoryConfig } from '../bean/MemoryConfig.js'; -import { LogStruct } from './ui-worker/ProcedureWorkerLog.js'; -import { HiSysEventStruct } from './ui-worker/ProcedureWorkerHiSysEvent.js'; - -class DataWorkerThread extends Worker { +import { FileInfo } from '../../js-heap/model/UiStruct'; +import { AppStartupStruct } from './ui-worker/ProcedureWorkerAppStartup'; +import { SoStruct } from './ui-worker/ProcedureWorkerSoInit'; +import { HeapTreeDataBean } from './logic-worker/ProcedureLogicWorkerCommon'; +import { TaskTabStruct } from '../component/trace/sheet/task/TabPaneTaskFrames'; +import { type DeviceStruct } from '../bean/FrameComponentBean'; +import { type FrameSpacingStruct } from './ui-worker/ProcedureWorkerFrameSpacing'; +import { type FrameDynamicStruct } from './ui-worker/ProcedureWorkerFrameDynamic'; +import { type FrameAnimationStruct } from './ui-worker/ProcedureWorkerFrameAnimation'; +import { type SnapshotStruct } from './ui-worker/ProcedureWorkerSnapshot'; +import { type MemoryConfig } from '../bean/MemoryConfig'; +import { LogStruct } from './ui-worker/ProcedureWorkerLog'; +import { HiSysEventStruct } from './ui-worker/ProcedureWorkerHiSysEvent'; + +class DataWorkerThread { taskMap: any = {}; - + worker?:Worker; + constructor(worker:Worker) { + this.worker = worker; + } uuid(): string { // @ts-ignore return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c: any) => @@ -110,16 +113,20 @@ class DataWorkerThread extends Worker { action: action, args: args, }; - this.postMessage(msg); + this.worker!.postMessage(msg); } } -class DbThread extends Worker { +class DbThread { busy: boolean = false; isCancelled: boolean = false; id: number = -1; taskMap: any = {}; cacheArray: Array = []; + worker?:Worker; + constructor(worker:Worker) { + this.worker=worker; + } uuid(): string { // @ts-ignore @@ -139,7 +146,7 @@ class DbThread extends Worker { sql: sql, params: args, }; - this.postMessage(msg); + this.worker!.postMessage(msg); } cutFileByRange( @@ -157,7 +164,7 @@ class DbThread extends Worker { handler(res.cutStatus, res.msg); } }; - this.postMessage( + this.worker!.postMessage( { id: id, action: 'cut-file', @@ -192,7 +199,7 @@ class DbThread extends Worker { resolve({ status: res.init, msg: res.msg }); } }; - this.postMessage( + this.worker!.postMessage( { id: id, action: 'open', @@ -206,7 +213,7 @@ class DbThread extends Worker { }; resetWASM() { - this.postMessage({ + this.worker!.postMessage({ id: this.uuid(), action: 'reset', }); @@ -246,16 +253,17 @@ export class DbPool { thread = threadBuild(); } else { if (type === 'wasm') { - thread = new DbThread('trace/database/TraceWorker.js'); + thread = new DbThread(new Worker(new URL('./TraceWorker',import.meta.url))); } else if (type === 'server') { - thread = new DbThread('trace/database/SqlLiteWorker.js'); + thread = new DbThread(new Worker(new URL('./SqlLiteWorker',import.meta.url))); } else if (type === 'sqlite') { - thread = new DbThread('trace/database/SqlLiteWorker.js'); + thread = new DbThread(new Worker(new URL('./SqlLiteWorker',import.meta.url))); } } + if (thread) { this.currentWasmThread = thread; - thread!.onmessage = (event: MessageEvent) => { + thread!.worker!.onmessage = (event: MessageEvent) => { thread!.busy = false; if (Reflect.has(thread!.taskMap, event.data.id)) { if (event.data.results) { @@ -297,8 +305,12 @@ export class DbPool { } } }; - thread!.onmessageerror = (e) => {}; - thread!.onerror = (e) => {}; + thread!.worker!.onmessageerror = (e) => { + console.log(e); + }; + thread!.worker!.onerror = (e) => { + console.log(e); + }; thread!.id = i; thread!.busy = false; this.works?.push(thread!); @@ -345,7 +357,7 @@ export class DbPool { clearInterval(this.cutDownTimer); for (let i = 0; i < this.works.length; i++) { let thread = this.works[i]; - thread.terminate(); + thread.worker!.terminate(); } this.works.length = 0; }; diff --git a/ide/src/trace/database/SqlLiteWorker.ts b/ide/src/trace/database/SqlLiteWorker.ts index b0f4a020c..aec8b517d 100644 --- a/ide/src/trace/database/SqlLiteWorker.ts +++ b/ide/src/trace/database/SqlLiteWorker.ts @@ -13,7 +13,8 @@ * limitations under the License. */ -importScripts('sql-wasm.js', 'TempSql.js'); +importScripts('sql-wasm.js'); +import {temp_init_sql_list} from "./TempSql"; let conn: any = null; let encoder = new TextEncoder(); function initIndexedDB() { diff --git a/ide/src/trace/database/TempSql.ts b/ide/src/trace/database/TempSql.ts index ec61a763d..f14312ede 100644 --- a/ide/src/trace/database/TempSql.ts +++ b/ide/src/trace/database/TempSql.ts @@ -399,3 +399,4 @@ let delete_callstack_binder_data = `DELETE or name = 'binder async rcv';`; let temp_init_sql_list = [temp_query_process]; +export { temp_init_sql_list }; diff --git a/ide/src/trace/database/TraceWorker.ts b/ide/src/trace/database/TraceWorker.ts index b4e213ab2..4ca57a55d 100644 --- a/ide/src/trace/database/TraceWorker.ts +++ b/ide/src/trace/database/TraceWorker.ts @@ -13,7 +13,8 @@ * limitations under the License. */ -importScripts('trace_streamer_builtin.js', 'TempSql.js'); +importScripts('trace_streamer_builtin.js'); +import {temp_init_sql_list} from "./TempSql"; let Module: any = null; let enc = new TextEncoder(); @@ -360,7 +361,6 @@ self.onmessage = async (e: MessageEvent) => { }); return; } - // @ts-ignore temp_init_sql_list.forEach((item, index) => { let r = createView(item); // @ts-ignore diff --git a/ide/src/trace/database/TraceWorkerRoot.ts b/ide/src/trace/database/TraceWorkerRoot.ts deleted file mode 100644 index 07aac33f2..000000000 --- a/ide/src/trace/database/TraceWorkerRoot.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -let worker: Worker; -self.onmessage = (e) => { - if (e.data.action === 'open') { - worker = new Worker('TraceWorker.js'); - worker.onmessage = (msg) => { - self.postMessage(msg.data); - }; - worker.postMessage(e.data, [e.data.buffer]); - } else if (e.data.action === 'exec') { - worker.postMessage(e.data); - } else if (e.data.action == 'exec-buf') { - // @ts-ignore - worker.postMessage(e.data); - } -}; -self.onerror = (event) => { - worker.terminate(); -}; -self.onclose = () => { - worker.terminate(); -}; diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorker.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorker.ts index 36f548bdf..1e5b7883a 100644 --- a/ide/src/trace/database/logic-worker/ProcedureLogicWorker.ts +++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorker.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { ProcedureLogicWorkerPerf } from './ProcedureLogicWorkerPerf.js'; -import { ProcedureLogicWorkerNativeMemory } from './ProcedureLogicWorkerNativeNemory.js'; -import { ProcedureLogicWorkerFileSystem } from './ProcedureLogicWorkerFileSystem.js'; -import { ProcedureLogicWorkerSPT } from './ProcedureLogicWorkerSPT.js'; -import { ProcedureLogicWorkerCpuState } from './ProcedureLogicWorkerCpuState.js'; -import { ProcedureLogicWorkerSchedulingAnalysis } from './ProcedureLogicWorkerSchedulingAnalysis.js'; -import { DataCache } from './ProcedureLogicWorkerCommon.js'; -import { ProcedureLogicWorkerJsCpuProfiler } from './ProcedureLogicWorkerJsCpuProfiler.js'; +import { ProcedureLogicWorkerPerf } from './ProcedureLogicWorkerPerf'; +import { ProcedureLogicWorkerNativeMemory } from './ProcedureLogicWorkerNativeNemory'; +import { ProcedureLogicWorkerFileSystem } from './ProcedureLogicWorkerFileSystem'; +import { ProcedureLogicWorkerSPT } from './ProcedureLogicWorkerSPT'; +import { ProcedureLogicWorkerCpuState } from './ProcedureLogicWorkerCpuState'; +import { ProcedureLogicWorkerSchedulingAnalysis } from './ProcedureLogicWorkerSchedulingAnalysis'; +import { DataCache } from './ProcedureLogicWorkerCommon'; +import { ProcedureLogicWorkerJsCpuProfiler } from './ProcedureLogicWorkerJsCpuProfiler'; let logicWorker: any = { perf: new ProcedureLogicWorkerPerf(), diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerCpuState.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerCpuState.ts index 7b2eedd79..fa076d509 100644 --- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerCpuState.ts +++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerCpuState.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { convertJSON, LogicHandler } from './ProcedureLogicWorkerCommon.js'; +import { convertJSON, LogicHandler } from './ProcedureLogicWorkerCommon'; export class ProcedureLogicWorkerCpuState extends LogicHandler { currentEventId: string = ''; diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerFileSystem.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerFileSystem.ts index 16ea6aec3..14cb702cd 100644 --- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerFileSystem.ts +++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerFileSystem.ts @@ -25,7 +25,7 @@ import { merageBeanDataSplit, postMessage, setFileName, -} from './ProcedureLogicWorkerCommon.js'; +} from './ProcedureLogicWorkerCommon'; export let FILE_TYPE_MAP = { '0': 'OPEN', diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerJsCpuProfiler.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerJsCpuProfiler.ts index f680e42b1..7cc31c7f6 100644 --- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerJsCpuProfiler.ts +++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerJsCpuProfiler.ts @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { JsCpuProfilerChartFrame, JsCpuProfilerTabStruct, type JsCpuProfilerUIStruct } from '../../bean/JsStruct.js'; -import { DataCache, type JsProfilerSymbol, LogicHandler, convertJSON } from './ProcedureLogicWorkerCommon.js'; +import { JsCpuProfilerChartFrame, JsCpuProfilerTabStruct, type JsCpuProfilerUIStruct } from '../../bean/JsStruct'; +import { DataCache, type JsProfilerSymbol, LogicHandler, convertJSON } from './ProcedureLogicWorkerCommon'; const ROOT_ID = 1; const LAMBDA_FUNCTION_NAME = '(anonymous)'; diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerNativeNemory.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerNativeNemory.ts index 4a9eddbdb..2e478f43c 100644 --- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerNativeNemory.ts +++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerNativeNemory.ts @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { FilterByAnalysis, NativeMemoryExpression } from '../../bean/NativeHook.js'; +import { FilterByAnalysis, NativeMemoryExpression } from '../../bean/NativeHook'; import { convertJSON, DataCache, @@ -23,7 +23,7 @@ import { merageBeanDataSplit, postMessage, setFileName, -} from './ProcedureLogicWorkerCommon.js'; +} from './ProcedureLogicWorkerCommon'; export class ProcedureLogicWorkerNativeMemory extends LogicHandler { selectTotalSize = 0; diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts index 28c40973c..9888a72d2 100644 --- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts +++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { LogicHandler, ChartStruct, convertJSON, DataCache, HiPerfSymbol } from './ProcedureLogicWorkerCommon.js'; -import { PerfBottomUpStruct } from '../../bean/PerfBottomUpStruct.js'; -import { HiPerfChartFrame } from '../../bean/PerfStruct.js'; +import { LogicHandler, ChartStruct, convertJSON, DataCache, HiPerfSymbol } from './ProcedureLogicWorkerCommon'; +import { PerfBottomUpStruct } from '../../bean/PerfBottomUpStruct'; +import { HiPerfChartFrame } from '../../bean/PerfStruct'; const systemRuleName: string = '/system/'; const numRuleName: string = '/max/min/'; diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerSPT.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerSPT.ts index 9ddf18efc..f431c5b0e 100644 --- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerSPT.ts +++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerSPT.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { convertJSON, LogicHandler } from './ProcedureLogicWorkerCommon.js'; -import { SliceGroup } from '../../bean/StateProcessThread.js'; +import { convertJSON, LogicHandler } from './ProcedureLogicWorkerCommon'; +import { SliceGroup } from '../../bean/StateProcessThread'; export class ProcedureLogicWorkerSPT extends LogicHandler { threadSlice: Array = []; diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerSchedulingAnalysis.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerSchedulingAnalysis.ts index dfd5f8ff1..607eccebf 100644 --- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerSchedulingAnalysis.ts +++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerSchedulingAnalysis.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { convertJSON, getProbablyTime, LogicHandler } from './ProcedureLogicWorkerCommon.js'; +import { convertJSON, getProbablyTime, LogicHandler } from './ProcedureLogicWorkerCommon'; export class ProcedureLogicWorkerSchedulingAnalysis extends LogicHandler { currentEventId: string = ''; diff --git a/ide/src/trace/database/ui-worker/ProcedureWorker.ts b/ide/src/trace/database/ui-worker/ProcedureWorker.ts index 0fd1daf60..906db554b 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorker.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorker.ts @@ -13,51 +13,51 @@ * limitations under the License. */ -import { CpuRender, EmptyRender } from './ProcedureWorkerCPU.js'; -import { RequestMessage } from './ProcedureWorkerCommon.js'; -import { FreqRender } from './ProcedureWorkerFreq.js'; -import { ProcessRender } from './ProcedureWorkerProcess.js'; -import { MemRender } from './ProcedureWorkerMem.js'; -import { ThreadRender } from './ProcedureWorkerThread.js'; -import { FuncRender } from './ProcedureWorkerFunc.js'; -import { FpsRender } from './ProcedureWorkerFPS.js'; -import { HeapRender, NativeMemoryRender } from './ProcedureWorkerHeap.js'; -import { CpuAbilityRender } from './ProcedureWorkerCpuAbility.js'; -import { MemoryAbilityRender } from './ProcedureWorkerMemoryAbility.js'; -import { DiskIoAbilityRender } from './ProcedureWorkerDiskIoAbility.js'; -import { NetworkAbilityRender } from './ProcedureWorkerNetworkAbility.js'; -import { HiperfCpuRender } from './ProcedureWorkerHiPerfCPU.js'; -import { HiperfProcessRender } from './ProcedureWorkerHiPerfProcess.js'; -import { HiperfThreadRender } from './ProcedureWorkerHiPerfThread.js'; -import { HiperfEventRender } from './ProcedureWorkerHiPerfEvent.js'; -import { HiperfReportRender } from './ProcedureWorkerHiPerfReport.js'; -import { VirtualMemoryRender } from './ProcedureWorkerVirtualMemory.js'; -import { FileSystemRender } from './ProcedureWorkerFileSystem.js'; -import { info } from '../../../log/Log.js'; -import { SdkSliceRender } from './ProduceWorkerSdkSlice.js'; -import { SdkCounterRender } from './ProduceWorkerSdkCounter.js'; -import { CpuStateRender } from './ProcedureWorkerCpuState.js'; -import { EnergyAnomalyRender } from './ProcedureWorkerEnergyAnomaly.js'; -import { EnergySystemRender } from './ProcedureWorkerEnergySystem.js'; -import { EnergyPowerRender } from './ProcedureWorkerEnergyPower.js'; -import { EnergyStateRender } from './ProcedureWorkerEnergyState.js'; -import { CpuFreqLimitRender } from './ProcedureWorkerCpuFreqLimits.js'; -import { ClockRender } from './ProcedureWorkerClock.js'; -import { IrqRender } from './ProcedureWorkerIrq.js'; -import { JankRender } from './ProcedureWorkerJank.js'; -import { HeapTimelineRender } from './ProcedureWorkerHeapTimeline.js'; -import { HeapSnapshotRender } from './ProcedureWorkerHeapSnapshot.js'; -import { translateJsonString } from '../logic-worker/ProcedureLogicWorkerCommon.js'; -import { AppStartupRender } from './ProcedureWorkerAppStartup.js'; -import { SoRender } from './ProcedureWorkerSoInit.js'; -import { FrameDynamicRender } from './ProcedureWorkerFrameDynamic.js'; -import { FrameAnimationRender } from './ProcedureWorkerFrameAnimation.js'; -import { FrameSpacingRender } from './ProcedureWorkerFrameSpacing.js'; -import { JsCpuProfilerRender } from './ProcedureWorkerCpuProfiler.js'; -import { SnapshotRender } from './ProcedureWorkerSnapshot.js'; -import { LogRender } from './ProcedureWorkerLog.js'; -import { HiPerfCallChartRender } from './ProcedureWorkerHiPerfCallChart.js'; -import { HiSysEventRender } from './ProcedureWorkerHiSysEvent.js'; +import { CpuRender, EmptyRender } from './ProcedureWorkerCPU'; +import { RequestMessage } from './ProcedureWorkerCommon'; +import { FreqRender } from './ProcedureWorkerFreq'; +import { ProcessRender } from './ProcedureWorkerProcess'; +import { MemRender } from './ProcedureWorkerMem'; +import { ThreadRender } from './ProcedureWorkerThread'; +import { FuncRender } from './ProcedureWorkerFunc'; +import { FpsRender } from './ProcedureWorkerFPS'; +import { HeapRender, NativeMemoryRender } from './ProcedureWorkerHeap'; +import { CpuAbilityRender } from './ProcedureWorkerCpuAbility'; +import { MemoryAbilityRender } from './ProcedureWorkerMemoryAbility'; +import { DiskIoAbilityRender } from './ProcedureWorkerDiskIoAbility'; +import { NetworkAbilityRender } from './ProcedureWorkerNetworkAbility'; +import { HiperfCpuRender } from './ProcedureWorkerHiPerfCPU'; +import { HiperfProcessRender } from './ProcedureWorkerHiPerfProcess'; +import { HiperfThreadRender } from './ProcedureWorkerHiPerfThread'; +import { HiperfEventRender } from './ProcedureWorkerHiPerfEvent'; +import { HiperfReportRender } from './ProcedureWorkerHiPerfReport'; +import { VirtualMemoryRender } from './ProcedureWorkerVirtualMemory'; +import { FileSystemRender } from './ProcedureWorkerFileSystem'; +import { info } from '../../../log/Log'; +import { SdkSliceRender } from './ProduceWorkerSdkSlice'; +import { SdkCounterRender } from './ProduceWorkerSdkCounter'; +import { CpuStateRender } from './ProcedureWorkerCpuState'; +import { EnergyAnomalyRender } from './ProcedureWorkerEnergyAnomaly'; +import { EnergySystemRender } from './ProcedureWorkerEnergySystem'; +import { EnergyPowerRender } from './ProcedureWorkerEnergyPower'; +import { EnergyStateRender } from './ProcedureWorkerEnergyState'; +import { CpuFreqLimitRender } from './ProcedureWorkerCpuFreqLimits'; +import { ClockRender } from './ProcedureWorkerClock'; +import { IrqRender } from './ProcedureWorkerIrq'; +import { JankRender } from './ProcedureWorkerJank'; +import { HeapTimelineRender } from './ProcedureWorkerHeapTimeline'; +import { HeapSnapshotRender } from './ProcedureWorkerHeapSnapshot'; +import { translateJsonString } from '../logic-worker/ProcedureLogicWorkerCommon'; +import { AppStartupRender } from './ProcedureWorkerAppStartup'; +import { SoRender } from './ProcedureWorkerSoInit'; +import { FrameDynamicRender } from './ProcedureWorkerFrameDynamic'; +import { FrameAnimationRender } from './ProcedureWorkerFrameAnimation'; +import { FrameSpacingRender } from './ProcedureWorkerFrameSpacing'; +import { JsCpuProfilerRender } from './ProcedureWorkerCpuProfiler'; +import { SnapshotRender } from './ProcedureWorkerSnapshot'; +import { LogRender } from './ProcedureWorkerLog'; +import { HiPerfCallChartRender } from './ProcedureWorkerHiPerfCallChart'; +import { HiSysEventRender } from './ProcedureWorkerHiSysEvent'; let dataList: any = {}; let dataList2: any = {}; diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerAppStartup.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerAppStartup.ts index 000445358..72b37293f 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerAppStartup.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerAppStartup.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseStruct, dataFilterHandler, drawString } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { BaseStruct, dataFilterHandler, drawString } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; export class AppStartupRender { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCPU.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCPU.ts index 7bb0d61b5..d70d006b7 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCPU.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCPU.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; import { BaseStruct, dataFilterHandler, @@ -25,9 +25,9 @@ import { drawWakeUpList, Render, RequestMessage, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { SpSystemTrace } from '../../component/SpSystemTrace.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { SpSystemTrace } from '../../component/SpSystemTrace'; export class EmptyRender extends Render { renderMainThread(req: any, row: TraceRow) { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerClock.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerClock.ts index 734274b33..8fe3c9f39 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerClock.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerClock.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseStruct, dataFilterHandler, isFrameContainPoint, Render } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { BaseStruct, dataFilterHandler, isFrameContainPoint, Render } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; export class ClockRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts index c37ed2773..7a2deff49 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { CpuStruct, WakeupBean } from './ProcedureWorkerCPU.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { CpuStruct, WakeupBean } from './ProcedureWorkerCPU'; +import { TraceRow } from '../../component/trace/base/TraceRow'; import { TimerShaftElement } from '../../component/trace/TimerShaftElement'; -import { Flag } from '../../component/trace/timer-shaft/Flag.js'; +import { Flag } from '../../component/trace/timer-shaft/Flag'; export abstract class Render { abstract renderMainThread(req: any, row: TraceRow): void; diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCpuAbility.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCpuAbility.ts index 71d2c66f0..57d750a4c 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCpuAbility.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCpuAbility.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; import { BaseStruct, dataFilterHandler, @@ -21,9 +21,9 @@ import { ns2x, RequestMessage, Render, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { DiskAbilityMonitorStruct } from './ProcedureWorkerDiskIoAbility.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { DiskAbilityMonitorStruct } from './ProcedureWorkerDiskIoAbility'; export class CpuAbilityRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCpuFreqLimits.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCpuFreqLimits.ts index f4e46ac91..9f4c51fb7 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCpuFreqLimits.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCpuFreqLimits.ts @@ -24,10 +24,10 @@ import { drawFlagLine, RequestMessage, drawSelection, -} from './ProcedureWorkerCommon.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { convertJSON } from '../logic-worker/ProcedureLogicWorkerCommon.js'; +} from './ProcedureWorkerCommon'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { convertJSON } from '../logic-worker/ProcedureLogicWorkerCommon'; export class CpuFreqLimitRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCpuProfiler.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCpuProfiler.ts index 4624a047f..5cc451c93 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCpuProfiler.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCpuProfiler.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { BaseStruct, type Rect, Render, drawString, isFrameContainPoint, ns2x } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { type JsCpuProfilerChartFrame } from '../../bean/JsStruct.js'; +import { BaseStruct, type Rect, Render, drawString, isFrameContainPoint, ns2x } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { type JsCpuProfilerChartFrame } from '../../bean/JsStruct'; export class JsCpuProfilerRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCpuState.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCpuState.ts index 9c6daacf0..66133035e 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCpuState.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCpuState.ts @@ -25,10 +25,10 @@ import { PerfRender, Render, RequestMessage, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { convertJSON } from '../logic-worker/ProcedureLogicWorkerCommon.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { convertJSON } from '../logic-worker/ProcedureLogicWorkerCommon'; export class CpuStateRender extends PerfRender { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerDiskIoAbility.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerDiskIoAbility.ts index f8987b41e..b82d5e5ac 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerDiskIoAbility.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerDiskIoAbility.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; import { BaseStruct, drawLines, @@ -25,8 +25,8 @@ import { drawFlagLine, RequestMessage, dataFilterHandler, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class DiskIoAbilityRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyAnomaly.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyAnomaly.ts index 7771350e4..e2f235eeb 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyAnomaly.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyAnomaly.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; import { BaseStruct, drawFlagLine, @@ -23,8 +23,8 @@ import { isFrameContainPoint, PerfRender, RequestMessage, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class EnergyAnomalyRender extends PerfRender { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyPower.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyPower.ts index 5d491b9c1..d4a3877c7 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyPower.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyPower.ts @@ -23,8 +23,8 @@ import { RequestMessage, drawSelection, isFrameContainPoint, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class EnergyPowerRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyState.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyState.ts index 0868eb700..37fb24d25 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyState.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerEnergyState.ts @@ -23,8 +23,8 @@ import { ns2x, Render, RequestMessage, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class EnergyStateRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerEnergySystem.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerEnergySystem.ts index 0de99ab6c..237834bdf 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerEnergySystem.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerEnergySystem.ts @@ -23,8 +23,8 @@ import { ns2x, Render, RequestMessage, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class EnergySystemRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerFPS.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerFPS.ts index 9a2d142d7..27fc10735 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerFPS.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerFPS.ts @@ -24,8 +24,8 @@ import { Rect, Render, RequestMessage, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class FpsRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerFileSystem.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerFileSystem.ts index 1cf4f75e2..5fe12b249 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerFileSystem.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerFileSystem.ts @@ -21,8 +21,8 @@ import { drawSelection, PerfRender, RequestMessage, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class FileSystemRender extends PerfRender { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerFrameAnimation.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerFrameAnimation.ts index 8792687a2..f23ff40f2 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerFrameAnimation.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerFrameAnimation.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { BaseStruct, drawString, isFrameContainPoint, ns2x, Rect, Render } from './ProcedureWorkerCommon.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { BaseStruct, drawString, isFrameContainPoint, ns2x, Rect, Render } from './ProcedureWorkerCommon'; export class FrameAnimationRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerFrameDynamic.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerFrameDynamic.ts index 01e5dce0e..2c0ff5031 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerFrameDynamic.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerFrameDynamic.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { BaseStruct, computeUnitWidth, isSurroundingPoint, ns2x, Rect, Render } from './ProcedureWorkerCommon.js'; -import { type AnimationRanges } from '../../bean/FrameComponentBean.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { BaseStruct, computeUnitWidth, isSurroundingPoint, ns2x, Rect, Render } from './ProcedureWorkerCommon'; +import { type AnimationRanges } from '../../bean/FrameComponentBean'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; export class FrameDynamicRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerFrameSpacing.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerFrameSpacing.ts index 0d6ae0d62..45b6ea727 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerFrameSpacing.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerFrameSpacing.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { BaseStruct, computeUnitWidth, isSurroundingPoint, ns2x, Rect, Render } from './ProcedureWorkerCommon.js'; -import { type AnimationRanges } from '../../bean/FrameComponentBean.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { BaseStruct, computeUnitWidth, isSurroundingPoint, ns2x, Rect, Render } from './ProcedureWorkerCommon'; +import { type AnimationRanges } from '../../bean/FrameComponentBean'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; export class FrameSpacingRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerFreq.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerFreq.ts index 3e7744f83..1661717aa 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerFreq.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerFreq.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { BaseStruct, dataFilterHandler, isFrameContainPoint, Render, RequestMessage } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { BaseStruct, dataFilterHandler, isFrameContainPoint, Render, RequestMessage } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class FreqRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts index 5c7dc8687..d34ec56c6 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { TraceRow } from '../../component/trace/base/TraceRow'; import { BaseStruct, isFrameContainPoint, @@ -23,9 +23,9 @@ import { Render, RequestMessage, drawString, -} from './ProcedureWorkerCommon.js'; -import { FuncStruct as BaseFuncStruct } from '../../bean/FuncStruct.js'; -import { FlagsConfig } from '../../component/SpFlags.js'; +} from './ProcedureWorkerCommon'; +import { FuncStruct as BaseFuncStruct } from '../../bean/FuncStruct'; +import { FlagsConfig } from '../../component/SpFlags'; export class FuncRender extends Render { renderMainThread( req: { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerHeap.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerHeap.ts index f209e2921..0f455b953 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerHeap.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerHeap.ts @@ -26,9 +26,9 @@ import { RequestMessage, isFrameContainPoint, ns2x, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { HeapStruct as BaseHeapStruct } from '../../bean/HeapStruct.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { HeapStruct as BaseHeapStruct } from '../../bean/HeapStruct'; export class NativeMemoryRender extends Render { renderMainThread(req: any, row: TraceRow) {} } diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerHeapSnapshot.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerHeapSnapshot.ts index 2d5993829..6af013128 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerHeapSnapshot.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerHeapSnapshot.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BaseStruct, Rect, Render, isFrameContainPoint } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { Utils } from '../../component/trace/base/Utils.js'; +import { BaseStruct, Rect, Render, isFrameContainPoint } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { Utils } from '../../component/trace/base/Utils'; export class HeapSnapshotRender extends Render { renderMainThread( req: { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerHeapTimeline.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerHeapTimeline.ts index c5960e14a..57ad84597 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerHeapTimeline.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerHeapTimeline.ts @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseStruct, Rect, isFrameContainPoint } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { HeapSample } from '../../../js-heap/model/DatabaseStruct.js'; +import { BaseStruct, Rect, isFrameContainPoint } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { HeapSample } from '../../../js-heap/model/DatabaseStruct'; export class HeapTimelineRender { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCPU.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCPU.ts index 831f27a9f..2b2081313 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCPU.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCPU.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; import { HiPerfStruct, hiPerf, PerfRender, RequestMessage, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class HiperfCpuRender extends PerfRender { renderMainThread(req: any, row: TraceRow): void { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCallChart.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCallChart.ts index 8cb120c00..b2ae06f45 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCallChart.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCallChart.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; import { BaseStruct, type Rect, @@ -21,9 +21,9 @@ import { drawString, Render, isFrameContainPoint -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { HiPerfChartFrame } from '../../bean/PerfStruct.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { HiPerfChartFrame } from '../../bean/PerfStruct'; export class HiPerfCallChartRender extends Render { renderMainThread(req: any, row: TraceRow): void { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfEvent.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfEvent.ts index ba3749efc..61468f7b9 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfEvent.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfEvent.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { hiPerf, HiPerfStruct, PerfRender, RequestMessage } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { hiPerf, HiPerfStruct, PerfRender, RequestMessage } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class HiperfEventRender extends PerfRender { renderMainThread(hiPerfEventReq: any, row: TraceRow): void { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfProcess.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfProcess.ts index 51db538f4..96638bba6 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfProcess.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfProcess.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { hiPerf, HiPerfStruct, PerfRender, RequestMessage } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { hiPerf, HiPerfStruct, PerfRender, RequestMessage } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class HiperfProcessRender extends PerfRender { renderMainThread(hiPerfProcessReq: any, row: TraceRow): void { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfReport.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfReport.ts index 043bab367..dbb103382 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfReport.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfReport.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { HiPerfStruct, PerfRender, type RequestMessage } from './ProcedureWorkerCommon.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { HiPerfStruct, PerfRender, type RequestMessage } from './ProcedureWorkerCommon'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class HiperfReportRender extends PerfRender { renderMainThread(hiPerfReportReq: any, row: TraceRow): void { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfThread.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfThread.ts index eb8a668e8..d816d9b94 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfThread.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfThread.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { hiPerf, HiPerfStruct, PerfRender, RequestMessage } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { hiPerf, HiPerfStruct, PerfRender, RequestMessage } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class HiperfThreadRender extends PerfRender { renderMainThread(hiPerfThreadReq: any, row: TraceRow): void { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerHiSysEvent.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerHiSysEvent.ts index 2c1c5154b..ed7a0b196 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerHiSysEvent.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerHiSysEvent.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { BaseStruct, dataFilterHandler, ns2x, Rect, Render } from './ProcedureWorkerCommon.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { BaseStruct, dataFilterHandler, ns2x, Rect, Render } from './ProcedureWorkerCommon'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; export class HiSysEventRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerIrq.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerIrq.ts index f27b1c0ab..bbbb4dbe2 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerIrq.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerIrq.ts @@ -20,9 +20,9 @@ import { Rect, Render, drawString, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; export class IrqRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerJank.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerJank.ts index 88924004e..db370504b 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerJank.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerJank.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { JanksStruct } from '../../bean/JanksStruct.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { BaseStruct, isFrameContainPoint, ns2x, Render, RequestMessage, drawString } from './ProcedureWorkerCommon.js'; +import { JanksStruct } from '../../bean/JanksStruct'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { BaseStruct, isFrameContainPoint, ns2x, Render, RequestMessage, drawString } from './ProcedureWorkerCommon'; export class JankRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerLog.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerLog.ts index 88fad80c6..d120d36b7 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerLog.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerLog.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { ns2x, Rect, Render } from './ProcedureWorkerCommon.js'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { ns2x, Rect, Render } from './ProcedureWorkerCommon'; -import { BaseStruct } from '../../bean/BaseStruct.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { BaseStruct } from '../../bean/BaseStruct'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; const LOG_STRUCT_HEIGHT = 7; const X_PADDING = 5; diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerMem.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerMem.ts index 783afe8f9..e2ce4fa90 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerMem.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerMem.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { TraceRow } from '../../component/trace/base/TraceRow'; import { BaseStruct, drawFlagLine, @@ -28,9 +28,9 @@ import { Render, RequestMessage, mem, -} from './ProcedureWorkerCommon.js'; -import { CpuStruct } from './ProcedureWorkerCPU.js'; -import { ProcessMemStruct as BaseProcessMemStruct } from '../../bean/ProcessMemStruct.js'; +} from './ProcedureWorkerCommon'; +import { CpuStruct } from './ProcedureWorkerCPU'; +import { ProcessMemStruct as BaseProcessMemStruct } from '../../bean/ProcessMemStruct'; export class MemRender extends Render { renderMainThread( req: { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerMemoryAbility.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerMemoryAbility.ts index 1183cbe06..f328b69f1 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerMemoryAbility.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerMemoryAbility.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; import { BaseStruct, dataFilterHandler, @@ -25,8 +25,8 @@ import { RequestMessage, isFrameContainPoint, ns2x, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class MemoryAbilityRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerNetworkAbility.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerNetworkAbility.ts index f98577c51..7a546cd4d 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerNetworkAbility.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerNetworkAbility.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { dataFilterHandler, isFrameContainPoint, Render, RequestMessage, BaseStruct } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { dataFilterHandler, isFrameContainPoint, Render, RequestMessage, BaseStruct } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class NetworkAbilityRender extends Render { renderMainThread( req: { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerPerfCallchains.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerPerfCallchains.ts index e676b085f..170db83b7 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerPerfCallchains.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerPerfCallchains.ts @@ -12,10 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -class PerfCallChainThread extends Worker { +class PerfCallChainThread{ busy: boolean = false; taskMap: any = {}; + worker?:Worker; + + constructor(worker:Worker) { + this.worker=worker; + } + uuid(): string { // @ts-ignore return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c: any) => @@ -33,7 +38,7 @@ class PerfCallChainThread extends Worker { action: action || 'exec', params: args, }; - this.postMessage(msg); + this.worker!.postMessage(msg); } } @@ -44,15 +49,15 @@ export class PerfCallChainPool { close = async () => { for (let i = 0; i < this.works.length; i++) { let thread = this.works[i]; - thread.terminate(); + thread.worker!.terminate(); } this.works.length = 0; }; init = async () => { await this.close(); - let thread = new PerfCallChainThread('trace/component/chart/PerfDataQuery.js', { type: 'module' }); //trace/component/chart/PerfDataQuery.js - thread!.onmessage = (event: MessageEvent) => { + let thread = new PerfCallChainThread(new Worker(new URL('../../component/chart/PerfDataQuery',import.meta.url), { type: 'module' })); //trace/component/chart/PerfDataQuery.js + thread!.worker!.onmessage = (event: MessageEvent) => { thread.busy = false; let fun = thread.taskMap[event.data.id]; if (fun) { @@ -60,8 +65,8 @@ export class PerfCallChainPool { } Reflect.deleteProperty(thread.taskMap, event.data.id); }; - thread!.onmessageerror = (e) => {}; - thread!.onerror = (e) => {}; + thread!.worker!.onmessageerror = (e) => {}; + thread!.worker!.onerror = (e) => {}; thread!.busy = false; this.works?.push(thread!); }; diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerProcess.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerProcess.ts index e6e580660..6073013c5 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerProcess.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerProcess.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; import { BaseStruct, drawFlagLine, @@ -24,9 +24,9 @@ import { ns2x, Render, RequestMessage, -} from './ProcedureWorkerCommon.js'; -import { CpuStruct } from './ProcedureWorkerCPU.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { CpuStruct } from './ProcedureWorkerCPU'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class ProcessRender extends Render { renderMainThread(req: any, row: TraceRow) { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerSnapshot.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerSnapshot.ts index 35fdf2dd3..90734acd7 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerSnapshot.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerSnapshot.ts @@ -12,10 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BaseStruct, Rect, Render, isFrameContainPoint, ns2x } from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { Utils } from '../../component/trace/base/Utils.js'; -import { MemoryConfig } from '../../bean/MemoryConfig.js'; +import { BaseStruct, Rect, Render, isFrameContainPoint, ns2x } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { Utils } from '../../component/trace/base/Utils'; +import { MemoryConfig } from '../../bean/MemoryConfig'; export class SnapshotRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerSoInit.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerSoInit.ts index 1bb93b1e1..205b3847a 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerSoInit.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerSoInit.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { BaseStruct, isFrameContainPoint, ns2x, Render, RequestMessage, drawString } from './ProcedureWorkerCommon.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { BaseStruct, isFrameContainPoint, ns2x, Render, RequestMessage, drawString } from './ProcedureWorkerCommon'; export class SoRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts index b56d5dd76..23c168151 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts @@ -21,10 +21,10 @@ import { Render, RequestMessage, drawString, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { Utils } from '../../component/trace/base/Utils.js'; -import { ThreadStruct as BaseThreadStruct } from '../../bean/ThreadStruct.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { Utils } from '../../component/trace/base/Utils'; +import { ThreadStruct as BaseThreadStruct } from '../../bean/ThreadStruct'; export class ThreadRender extends Render { renderMainThread( threadReq: { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerTimeline.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerTimeline.ts index 5d93c9b80..ef5cd6a61 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerTimeline.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerTimeline.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { ns2s, Rect, Render, RequestMessage } from './ProcedureWorkerCommon.js'; -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { CpuStruct } from './ProcedureWorkerCPU.js'; +import { ns2s, Rect, Render, RequestMessage } from './ProcedureWorkerCommon'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { CpuStruct } from './ProcedureWorkerCPU'; //绘制时间轴 let timeRuler: TimeRuler | undefined; diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerVirtualMemory.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerVirtualMemory.ts index 3d43f6b0a..51e2ff5f5 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerVirtualMemory.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerVirtualMemory.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; import { BaseStruct, drawLines, @@ -24,8 +24,8 @@ import { drawFlagLine, drawSelection, isFrameContainPoint, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class VirtualMemoryRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProduceWorkerSdkCounter.ts b/ide/src/trace/database/ui-worker/ProduceWorkerSdkCounter.ts index 807daaac5..fcb5c8d45 100644 --- a/ide/src/trace/database/ui-worker/ProduceWorkerSdkCounter.ts +++ b/ide/src/trace/database/ui-worker/ProduceWorkerSdkCounter.ts @@ -23,8 +23,8 @@ import { RequestMessage, drawLines, drawLoading, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; export class SdkCounterRender extends Render { renderMainThread( diff --git a/ide/src/trace/database/ui-worker/ProduceWorkerSdkSlice.ts b/ide/src/trace/database/ui-worker/ProduceWorkerSdkSlice.ts index bad3969f4..f7abd77b4 100644 --- a/ide/src/trace/database/ui-worker/ProduceWorkerSdkSlice.ts +++ b/ide/src/trace/database/ui-worker/ProduceWorkerSdkSlice.ts @@ -24,9 +24,9 @@ import { isFrameContainPoint, ns2x, drawSelection, -} from './ProcedureWorkerCommon.js'; -import { TraceRow } from '../../component/trace/base/TraceRow.js'; -import { CounterStruct } from './ProduceWorkerSdkCounter.js'; +} from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { CounterStruct } from './ProduceWorkerSdkCounter'; export class SdkSliceRender extends Render { renderMainThread( diff --git a/ide/src/trace/grpc/HiProfilerClient.ts b/ide/src/trace/grpc/HiProfilerClient.ts index ad67d750a..9749e6187 100644 --- a/ide/src/trace/grpc/HiProfilerClient.ts +++ b/ide/src/trace/grpc/HiProfilerClient.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { Address, ProfilerClient } from './ProfilerClient.js'; +import { Address, ProfilerClient } from './ProfilerClient'; export class HiProfilerClient { private _client: ProfilerClient; diff --git a/ide/tsconfig.json b/ide/tsconfig.json index 57e2db39f..d25b14fc5 100644 --- a/ide/tsconfig.json +++ b/ide/tsconfig.json @@ -5,18 +5,18 @@ /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ - "target": "ES2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ - "module": "es2015", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ + "module": "ES2022", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ // "lib": [], /* Specify library files to be included in the compilation. */ -// "allowJs": true, /* Allow javascript files to be compiled. */ + "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist", /* Redirect output structure to the directory. */ - "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ +// "outDir": "./dist", /* Redirect output structure to the directory. */ +// "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ @@ -27,13 +27,13 @@ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ +// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ +// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ // "noUnusedLocals": true, /* Report errors on unused locals. */ @@ -48,8 +48,8 @@ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ +// "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ @@ -67,5 +67,5 @@ "skipLibCheck": true, /* Skip type checking of declaration files. */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ }, - "include": ["src"] + "files": ["src/index.ts"], } diff --git a/ide/webpack.config.js b/ide/webpack.config.js new file mode 100644 index 000000000..7820f79fa --- /dev/null +++ b/ide/webpack.config.js @@ -0,0 +1,204 @@ +// Generated using webpack-cli https://github.com/webpack/webpack-cli + +const path = require('path'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const isProduction = process.env.NODE_ENV === 'production'; +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const os = require('os'); +const childProcess = require('child_process'); +const { exec } = require('child_process'); +const fs = require('fs'); + + +function directoryExists(path) { + try { + fs.accessSync(path); + return true; + } catch (error) { + return false; + } +} + +function runCommand(command) { + return new Promise((resolve, reject) => { + exec(command, (error, stdout, stderr) => { + if (error) { + reject(error); + } else { + resolve(stdout); + } + }); + }); +} + +const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : 'style-loader'; +//compile server +((flag) => { + if (!flag) { + return; + } + console.log('start compile server'); + let outPath = path.normalize(path.join(__dirname, '/', 'dist')); + let serverSrc = path.normalize(path.join(__dirname, '/server/main.go')); + if (!directoryExists(outPath)){ + runCommand(`mkdir ${outPath}`); + } else { + runCommand(`rm -rf ${outPath}/* `).then((result)=>{ + + }); + } + let rs; + if (os.type() === 'Windows_NT') { + rs = childProcess.spawnSync('go', ['build', '-o', outPath, serverSrc], { + encoding: 'utf-8', + }); + } else { + rs = childProcess.spawnSync('go', ['build', '-o', outPath + '/main', serverSrc], { + encoding: 'utf-8', + }); + } + if (rs.status === 0) { + console.log('compile server success'); + } else { + console.error('compile server failed', rs); + } +})(true); +const config = { + entry: './src/index.ts', + output: { + path: path.resolve(__dirname, 'dist'), + filename: '[name].[chunkhash].bundle.js', + clean: false, + }, + devServer: { + open: true, + host: 'localhost', + }, + plugins: [ + new HtmlWebpackPlugin({ + template: 'index.html', + }), + new CleanWebpackPlugin({ + verbose: true, + cleanOnceBeforeBuildPatterns: ['!main'], + }), + new CopyWebpackPlugin({ + patterns: [ + { + from: './src/figures', + to: 'figures', + }, + { + from: './src/img', + to: 'img', + }, + { + from: './src/doc', + to: 'doc', + }, + { + from: './src/base-ui/icon.svg', + to: 'base-ui/icon.svg', + }, + { + from: './bin/trace_converter_builtin.js', + to: 'trace_converter_builtin.js', + }, + { + from: './bin/trace_converter_builtin.wasm', + to: 'trace_converter_builtin.wasm', + }, + { + from: './bin/trace_streamer_builtin.js', + to: 'trace_streamer_builtin.js', + }, + { + from: './bin/trace_streamer_builtin.wasm', + to: 'trace_streamer_builtin.wasm', + }, + { + from: './bin/trace_streamer_dubai_builtin.js', + to: 'trace_streamer_dubai_builtin.js', + }, + { + from: './bin/trace_streamer_dubai_builtin.wasm', + to: 'trace_streamer_dubai_builtin.wasm', + }, + { + from: './bin/trace_streamer_sdk_builtin.js', + to: 'trace_streamer_sdk_builtin.js', + }, + { + from: './bin/trace_streamer_sdk_builtin.wasm', + to: 'trace_streamer_sdk_builtin.wasm', + }, + { + from: './third-party/sql-wasm.js', + to: 'sql-wasm.js', + }, + { + from: './third-party/sql-wasm.wasm', + to: 'sql-wasm.wasm', + }, + { + from: './server/version.txt', + to: 'version.txt', + }, + { + from: './server/wasm.json', + to: 'wasm.json', + }, + ], + }), + // Add your plugins here + // Learn more about plugins from https://webpack.js.org/configuration/plugins/ + ], + module: { + rules: [ + { + test: /\.(ts|tsx)$/i, + loader: 'ts-loader', + exclude: ['/node_modules/'], + }, + { + test: /\.css$/i, + use: [stylesHandler, 'css-loader', 'postcss-loader'], + }, + { + test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, + type: 'asset', + }, + + // Add your rules for custom modules here + // Learn more about loaders from https://webpack.js.org/loaders/ + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.jsx', '.js', '...'], + fallback: { + fs: false, + tls: false, + net: false, + zlib: false, + http: false, + https: false, + stream: false, + crypto: false, + child_process: false, + path: false, //if you want to use this module also don't forget npm i crypto-browserify + }, + }, +}; + +module.exports = () => { + if (isProduction) { + config.mode = 'production'; + + config.plugins.push(new MiniCssExtractPlugin()); + } else { + config.mode = 'development'; + } + return config; +}; -- Gitee From 21bf805cea045929374b08a7e7c1c13a60521f30 Mon Sep 17 00:00:00 2001 From: zhangzepeng Date: Tue, 5 Dec 2023 19:14:11 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E2=80=98fix-1.=E8=B0=83=E7=94=A8=E6=A0=88?= =?UTF-8?q?=E5=86=8D=E6=AC=A1=E8=BE=93=E5=85=A5=E7=9B=B8=E5=90=8C=E7=9A=84?= =?UTF-8?q?=E5=85=B3=E9=94=AE=E5=AD=97=E8=A1=A8=E6=A0=BC=E6=9C=AA=E5=B1=95?= =?UTF-8?q?=E5=BC=802.Query-result=E4=B8=AD=E6=98=BE=E7=A4=BAsql=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=8F=90=E7=A4=BA3.perf=E8=B0=83=E7=94=A8=E6=A0=88?= =?UTF-8?q?=E6=9C=80=E5=A4=A7=E6=B7=B1=E5=BA=A6=E4=BB=8E128=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E4=B8=BA2564.=E6=A1=86=E9=80=89=E5=B8=A6binder-async?= =?UTF-8?q?=E6=B3=B3=E9=81=93-sliceTab=E4=B9=9F=E4=B8=8D=E6=98=BE=E7=A4=BA?= =?UTF-8?q?-binder-async-rcv/binder-transaction-async5.=E5=8A=A8=E6=95=88?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E4=B8=8D=E6=98=BE=E7=A4=BA=E2=80=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzepeng --- ide/src/base-ui/icon.svg | 93 +++++++------ ide/src/trace/SpApplication.ts | 2 +- ide/src/trace/component/SpQuerySQL.ts | 3 + .../trace/component/chart/SpFrameTimeChart.ts | 6 +- .../component/trace/base/TraceRowConfig.ts | 122 +++++++++++++----- .../trace/sheet/ark-ts/TabPaneJsCpu.ts | 4 +- .../sheet/file-system/TabPaneCallTree.ts | 2 + .../file-system/TabPaneFileSystemCalltree.ts | 2 + .../trace/sheet/hiperf/TabPerfBottomUp.ts | 31 +++-- .../trace/sheet/hiperf/TabPerfProfile.ts | 2 + .../sheet/native-memory/TabPaneNMCallTree.ts | 2 + .../trace/sheet/process/TabPaneSlices.ts | 2 +- ...empConfig.json => custom_temp_config.json} | 0 ide/src/trace/database/SqlLite.ts | 4 - .../logic-worker/ProcedureLogicWorkerPerf.ts | 2 +- 15 files changed, 176 insertions(+), 101 deletions(-) rename ide/src/trace/config/{customTempConfig.json => custom_temp_config.json} (100%) diff --git a/ide/src/base-ui/icon.svg b/ide/src/base-ui/icon.svg index 7424ce2a8..5524fca98 100644 --- a/ide/src/base-ui/icon.svg +++ b/ide/src/base-ui/icon.svg @@ -475,71 +475,70 @@ - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - + \ No newline at end of file diff --git a/ide/src/trace/SpApplication.ts b/ide/src/trace/SpApplication.ts index 8ec0a2a9a..b747672bb 100644 --- a/ide/src/trace/SpApplication.ts +++ b/ide/src/trace/SpApplication.ts @@ -555,7 +555,7 @@ export class SpApplication extends BaseElement { - + diff --git a/ide/src/trace/component/SpQuerySQL.ts b/ide/src/trace/component/SpQuerySQL.ts index 324482715..c4935db1c 100644 --- a/ide/src/trace/component/SpQuerySQL.ts +++ b/ide/src/trace/component/SpQuerySQL.ts @@ -164,6 +164,9 @@ export class SpQuerySQL extends BaseElement { private executeSql(sql: string): void { this.progressLoad!.loading = true; + if (this.querySize){ + this.querySize!.title = `${sql}`; + } queryCustomizeSelect(sql).then((resultList): void => { if (resultList && resultList.length > 0) { this.statDataArray = resultList; diff --git a/ide/src/trace/component/chart/SpFrameTimeChart.ts b/ide/src/trace/component/chart/SpFrameTimeChart.ts index d6fefd4bd..d4f823090 100644 --- a/ide/src/trace/component/chart/SpFrameTimeChart.ts +++ b/ide/src/trace/component/chart/SpFrameTimeChart.ts @@ -321,7 +321,7 @@ export class SpFrameTimeChart { frameAnimationRow.name = 'Animation'; frameAnimationRow.style.height = `${maxHeight}px`; frameAnimationRow.setAttribute('height', `${maxHeight}`); - frameAnimationRow.addTemplateTypes('Animation Effect'); + frameAnimationRow.addTemplateTypes('AnimationEffect'); frameAnimationRow.setAttribute('children', ''); frameAnimationRow.supplier = (): Promise => new Promise((resolve) => { @@ -370,7 +370,7 @@ export class SpFrameTimeChart { let labelName = dynamicCurveRow.shadowRoot?.querySelector('.name') as HTMLLabelElement; labelName.style.marginRight = '77px'; dynamicCurveRow.name = 'Animation Effect Curve'; - dynamicCurveRow.addTemplateTypes('Animation Effect'); + dynamicCurveRow.addTemplateTypes('AnimationEffect'); dynamicCurveRow.setAttribute('height', '100px'); dynamicCurveRow.setAttribute('children', ''); dynamicCurveRow.setAttribute('model-type', systemConfigList[0].name); @@ -423,7 +423,7 @@ export class SpFrameTimeChart { frameSpacingRow.style.width = '100%'; frameSpacingRow.style.height = '140px'; frameSpacingRow.name = 'Frame spacing'; - frameSpacingRow.addTemplateTypes('Animation Effect'); + frameSpacingRow.addTemplateTypes('AnimationEffect'); frameSpacingRow.setAttribute('height', '140'); frameSpacingRow.setAttribute('children', ''); frameSpacingRow.setAttribute('model-name', name); diff --git a/ide/src/trace/component/trace/base/TraceRowConfig.ts b/ide/src/trace/component/trace/base/TraceRowConfig.ts index ef8814805..cd34b616a 100644 --- a/ide/src/trace/component/trace/base/TraceRowConfig.ts +++ b/ide/src/trace/component/trace/base/TraceRowConfig.ts @@ -46,7 +46,6 @@ export class TraceRowConfig extends BaseElement { private otherRowNames: Array = []; private sceneList = [ 'FrameTimeline', - 'TaskPool', 'AnimationEffect', 'AppStartup', 'HiSysEvent', @@ -68,6 +67,9 @@ export class TraceRowConfig extends BaseElement { this.subsystemSelectList = []; this.otherRowNames = []; this.inputElement!.value = ''; + this.exportFileIcon!.style.display = 'none'; + this.backTemp!.style.display = 'none'; + this.configTitle!.innerHTML = 'Timeline Details'; this.spSystemTrace = this.parentElement!.querySelector('sp-system-trace'); this.traceRowList = this.spSystemTrace!.shadowRoot?.querySelector('div[class=rows-pane]')!.querySelectorAll>( @@ -81,9 +83,10 @@ export class TraceRowConfig extends BaseElement { isRefreshTopTable: boolean = false, isRefreshBottomTable: boolean = false, isSubSysConfig: boolean = false - ): void{ + ): void { let allowSceneList: Array = []; this.selectTypeList = []; + this.subsystemSelectList = []; let topPanel = new DocumentFragment(); let bottomPanel = new DocumentFragment(); this.traceRowList!.forEach((traceRow: TraceRow) => { @@ -92,6 +95,10 @@ export class TraceRowConfig extends BaseElement { nodeName: traceRow.name, scene: [...traceRow.templateType] }); + this.subsystemSelectList!.push({ + nodeName: traceRow.name, + scene: [...traceRow.templateType] + }); if (isRefreshTopTable) { this.sceneTable!.innerHTML = ''; if (traceRow.templateType.size > 0) { @@ -130,6 +137,7 @@ export class TraceRowConfig extends BaseElement { optionCheckBox.style.height = '100%'; optionCheckBox.title = item; optionCheckBox.addEventListener('change', () => { + this.subsystemSelectList = []; this.clearLines(optionCheckBox.title); if (optionCheckBox.checked) { this.selectTypeList!.push(item); @@ -228,6 +236,27 @@ export class TraceRowConfig extends BaseElement { } litCheckBox.checked = isShowCheck; }); + if (this.hasAttribute('temp_config')) { + this.refreshNodes(this.treeNodes); + this.refreshSelectList(this.treeNodes); + this.refreshTable(); + } + } + + refreshSelectList(nodes: SubsystemNode[]): void { + nodes.forEach((item) => { + if (item.depth === 3) { + if (item.isCheck) { + this.subsystemSelectList!.push({ + nodeName: item.nodeName, + scene: item.scene + }); + } + } + if (item.children.length > 0) { + this.refreshSelectList(item.children); + } + }); } resetChartTable(): void { @@ -280,17 +309,12 @@ export class TraceRowConfig extends BaseElement { } } }); - if(this.hasAttribute('temp_config')) { - // 按照this.selectTypeList 更新treeNodes - this.refreshNodes(this.treeNodes); - this.refreshTable(); - } } this.refreshSystemPanel(); } refreshNodes(nodes: SubsystemNode[]): void { - if(this.selectTypeList?.length !== 0) { + if (this.selectTypeList?.length !== 0) { for (let index = 0; index < nodes.length; index++) { let item = nodes[index]; let exists = false; @@ -300,7 +324,7 @@ export class TraceRowConfig extends BaseElement { return; } }); - if(exists) { + if (exists) { item.isCheck = true; } else { item.isCheck = false; @@ -376,7 +400,7 @@ export class TraceRowConfig extends BaseElement { let openFileIcon = this.shadowRoot?.querySelector('#open-file-icon'); this.configTitle = this.shadowRoot?.querySelector('#config_title'); let jsonUrl = `https://${window.location.host.split(':')[0]}:${window. - location.port}/application/trace/config/customTempConfig.json`; + location.port}/application/trace/config/custom_temp_config.json`; loadTemp!.addEventListener('click', () => { fetch(jsonUrl).then((res) => { if (res.ok) { @@ -419,7 +443,7 @@ export class TraceRowConfig extends BaseElement { this.filterFilterSearch(); }); this.backTemp!.addEventListener('click', () => { - this.init(); + this.refreshAllConfig(true, true); this.resetChartTable(); this.backTemp!.style.display = 'none'; this.exportFileIcon!.style.display = 'none'; @@ -450,14 +474,13 @@ export class TraceRowConfig extends BaseElement { let encoder = new TextEncoder(); let tempBuffer = encoder.encode(this.tempString!); a.href = URL.createObjectURL(new Blob([tempBuffer])); - a.download = 'customTempConfig'; + a.download = 'custom_config'; a.click(); window.URL.revokeObjectURL(a.href); } loadTempConfig(): void { this.selectTypeList = []; - this.subsystemSelectList = []; this.otherRowNames = []; this.refreshAllConfig(true, true); this.resetChartTable(); @@ -468,7 +491,7 @@ export class TraceRowConfig extends BaseElement { configJson = JSON.parse(this.tempString!); this.configTitle!.innerHTML = 'SubSystem Template'; let subsystemsKey: string = 'subsystems'; - if(!configJson[subsystemsKey]) { + if (!configJson[subsystemsKey]) { this.exportFileIcon!.style.display = 'none'; this.backTemp!.style.display = 'none'; this.configTitle!.innerHTML = 'Timeline Details'; @@ -486,7 +509,6 @@ export class TraceRowConfig extends BaseElement { this.treeNodes = this.buildSubSystemTreeData(id, configJson); this.buildTempOtherList(id); this.setAttribute('temp_config', ''); - this.subsystemSelectList = []; this.expandedNodeList.clear(); this.refreshTable(); } @@ -506,7 +528,8 @@ export class TraceRowConfig extends BaseElement { nodeName: currentSubName, children: [], depth: 1, - isCheck: true + isCheck: true, + scene: [] }; if (subSystems.indexOf(subsystemStruct) < 0) { let currentCompDates = currentSystemData.components; @@ -521,7 +544,8 @@ export class TraceRowConfig extends BaseElement { nodeName: currentCompName, children: [], depth: 2, - isCheck: true + isCheck: true, + scene: [] }; for (let chartIndex = 0; chartIndex < currentChartDates.length; chartIndex++) { let currentChartDate = currentChartDates[chartIndex]; @@ -591,7 +615,6 @@ export class TraceRowConfig extends BaseElement { refreshTable(): void { this.chartTable!.innerHTML = ''; - this.subsystemSelectList = []; for (let index = 0; index < this.treeNodes.length; index++) { this.buildSubsystem(this.treeNodes[index]); } @@ -638,7 +661,7 @@ export class TraceRowConfig extends BaseElement { let configCheckBox: LitCheckBox = new LitCheckBox(); configCheckBox.className = 'scene-check-box temp-chart-item'; configCheckBox.setAttribute('search_text', subsystemNode.nodeName!); - if(subsystemNode.scene) { + if (subsystemNode.scene) { configCheckBox.title = subsystemNode.scene.toString(); } configCheckBox.checked = subsystemNode.isCheck!; @@ -661,18 +684,55 @@ export class TraceRowConfig extends BaseElement { } } }); + let chartNumber = this.subsystemSelectList?.findIndex(item => item.nodeName === subsystemNode.nodeName!); if (configCheckBox.checked) { - this.subsystemSelectList?.push({ - nodeName: subsystemNode.nodeName!, - scene: Array(configCheckBox.title) - }); + if(chartNumber === -1) { + this.subsystemSelectList?.push({ + nodeName: subsystemNode.nodeName!, + scene: configCheckBox.title.split(',') + }); + } } else { - let chartNumber = this.subsystemSelectList?.findIndex(row => row.nodeName === subsystemNode.nodeName!); if (chartNumber !== undefined && chartNumber !== null) { this.subsystemSelectList?.splice(chartNumber, 1); } } } + + this.spSystemTrace?.collectRows.forEach((favoriteRow) => { + let isShowRow: boolean = false; + let favoriteName = ''; + if (this.subsystemSelectList!.length === 0) { + favoriteRow.removeAttribute('scene'); + favoriteRow.rowHidden = true; + } else { + if (favoriteRow.parentRowEl) { + favoriteRow.parentRowEl.expansion = false; + favoriteName = favoriteRow.parentRowEl!.name; + for (let i = 0; i < this.subsystemSelectList!.length; i++) { + if (this.subsystemSelectList![i].nodeName === favoriteName) { + isShowRow = true; + break; + } + } + } else { + favoriteName = favoriteRow.name; + for (let i = 0; i < this.subsystemSelectList!.length; i++) { + if (this.subsystemSelectList![i].nodeName === favoriteName) { + isShowRow = true; + break; + } + } + } + if (isShowRow) { + favoriteRow.rowHidden = false; + favoriteRow.setAttribute('scene', ''); + } else { + favoriteRow.removeAttribute('scene'); + favoriteRow.rowHidden = true; + } + } + }); this.refreshSystemPanel(); }); subsystemDiv.appendChild(configCheckBox); @@ -686,7 +746,7 @@ export class TraceRowConfig extends BaseElement { private buildTempOtherList(id: number): void { let otherRootNode: SubsystemNode = { - children: [], depth: 1, id: id, nodeName: 'other', isCheck: true + children: [], depth: 1, id: id, nodeName: 'other', isCheck: true, scene: [] }; for (let index = 0; index < this.otherRowNames!.length; index++) { otherRootNode.children.push({ @@ -707,13 +767,15 @@ export class TraceRowConfig extends BaseElement { if (node.children.length > 0) { node.children.forEach(childItem => { if (childItem.depth === 3) { + let chartNumber = this.subsystemSelectList?.findIndex(item => item.nodeName === childItem.nodeName!); if (configCheckBox.checked) { - this.subsystemSelectList?.push({ - nodeName: childItem.nodeName!, - scene: Array(configCheckBox.title) - }); + if(chartNumber === -1) { + this.subsystemSelectList?.push({ + nodeName: childItem.nodeName!, + scene: configCheckBox.title.split(',') + }); + } } else { - let chartNumber = this.subsystemSelectList?.findIndex(row => row.nodeName === node.nodeName!); if (chartNumber !== undefined && chartNumber !== null) { this.subsystemSelectList?.splice(chartNumber, 1); } diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts index fb9bfc5c6..a9654b5e5 100644 --- a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts @@ -183,9 +183,9 @@ export class TabPaneJsCpuCallTree extends BaseElement { if (this.searchValue !== this.profilerFilter!.filterValue) { this.searchValue = this.profilerFilter!.filterValue; findSearchNode(this.callTreeSource, this.searchValue, false); - this.callTreeTable!.setStatus(this.callTreeSource, true); - this.setCallTreeTableData(this.callTreeSource); } + this.callTreeTable!.setStatus(this.callTreeSource, true); + this.setCallTreeTableData(this.callTreeSource); }); } diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts index f584d8cb8..fcd02b482 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts @@ -558,6 +558,8 @@ export class TabPaneCallTree extends BaseElement { this.switchFlameChart(callTreeFilterData); }); } else { + this.callTreeTbl!.setStatus(this.callTreeDataSource, true); + this.setLTableData(this.callTreeDataSource); this.switchFlameChart(callTreeFilterData); } }); diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts index 514e87b91..767267fd6 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts @@ -506,6 +506,8 @@ export class TabpaneFilesystemCalltree extends BaseElement { this.switchFlameChart(data); }); } else { + this.fsCallTreeTbl!.setStatus(this.fsCallTreeDataSource, true); + this.setLTableData(this.fsCallTreeDataSource); this.switchFlameChart(data); } }); diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts index 137443c11..ed000f5f3 100644 --- a/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts @@ -51,9 +51,9 @@ export class TabpanePerfBottomUp extends BaseElement { if (this.searchValue !== this.bottomUpFilter!.filterValue) { this.searchValue = this.bottomUpFilter!.filterValue; findSearchNode(this.bottomUpSource, this.searchValue, false); - this.bottomUpTable!.setStatus(this.bottomUpSource, true); - this.setBottomUpTableData(this.bottomUpSource); } + this.bottomUpTable!.setStatus(this.bottomUpSource, true); + this.setBottomUpTableData(this.bottomUpSource); }); } @@ -98,18 +98,25 @@ export class TabpanePerfBottomUp extends BaseElement { const percentageDenominator = 100; const percentFraction = 1; this.stackTable!.recycleDataSource = []; - let sum = results.reduce((sum, struct) => { - sum.totalCount += struct.selfTime; - sum.totalEvent += struct.eventCount; - return sum; - }, { - totalCount: 0, - totalEvent: 0 - }); + let sum = results.reduce( + (sum, struct) => { + sum.totalCount += struct.selfTime; + sum.totalEvent += struct.eventCount; + return sum; + }, + { + totalCount: 0, + totalEvent: 0, + } + ); const setTabData = (array: Array): void => { array.forEach((data) => { - data.totalTimePercent = `${((data.totalTime / sum.totalCount) * percentageDenominator).toFixed(percentFraction)}%`; - data.selfTimePercent = `${((data.selfTime / sum.totalCount) * percentageDenominator).toFixed(percentFraction)}%`; + data.totalTimePercent = `${((data.totalTime / sum.totalCount) * percentageDenominator).toFixed( + percentFraction + )}%`; + data.selfTimePercent = `${((data.selfTime / sum.totalCount) * percentageDenominator).toFixed( + percentFraction + )}%`; data.eventPercent = `${((data.eventCount / sum.totalEvent) * percentageDenominator).toFixed(percentFraction)}%`; setTabData(data.children); }); diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts index 26f793aaa..e713b83fb 100644 --- a/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts @@ -516,6 +516,8 @@ export class TabpanePerfProfile extends BaseElement { this.switchFlameChart(data); }); } else { + this.perfProfilerTbl!.setStatus(this.perfProfilerDataSource, true); + this.setPerfProfilerLeftTableData(this.perfProfilerDataSource); this.switchFlameChart(data); } }); diff --git a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMCallTree.ts b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMCallTree.ts index 45d7358ce..60b5016c8 100644 --- a/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMCallTree.ts +++ b/ide/src/trace/component/trace/sheet/native-memory/TabPaneNMCallTree.ts @@ -668,6 +668,8 @@ export class TabpaneNMCalltree extends BaseElement { this.switchFlameChart(nmCallTreeData); }); } else { + this.nmCallTreeTbl!.setStatus(this.nmCallTreeSource, true); + this.setLTableData(this.nmCallTreeSource); this.switchFlameChart(nmCallTreeData); } } diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts b/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts index 6745fa1b4..aa154985c 100644 --- a/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts +++ b/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts @@ -125,7 +125,7 @@ export class TabPaneSlices extends BaseElement { for (const searchItem of search.list) { for (const traceRow of sliceRowList) { if ( - Math.max(TraceRow.rangeSelectObject?.startNS!, searchItem.startTime) < + Math.max(TraceRow.rangeSelectObject?.startNS!, searchItem.startTime) <= Math.min(TraceRow.rangeSelectObject?.endNS!, searchItem.startTime + searchItem.dur) && !rangeSelectList.includes(searchItem) ) { diff --git a/ide/src/trace/config/customTempConfig.json b/ide/src/trace/config/custom_temp_config.json similarity index 100% rename from ide/src/trace/config/customTempConfig.json rename to ide/src/trace/config/custom_temp_config.json diff --git a/ide/src/trace/database/SqlLite.ts b/ide/src/trace/database/SqlLite.ts index d9060747c..c2248e044 100644 --- a/ide/src/trace/database/SqlLite.ts +++ b/ide/src/trace/database/SqlLite.ts @@ -888,10 +888,6 @@ export const getTabSlices = ( T.tid in (${funTids.join(',')}) and P.pid in (${pids.join(',')}) - and - c.name != 'binder transaction async' - and - c.name != 'binder async rcv' and c.cookie is null and diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts index 9888a72d2..ee50ac07c 100644 --- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts +++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts @@ -19,7 +19,7 @@ import { HiPerfChartFrame } from '../../bean/PerfStruct'; const systemRuleName: string = '/system/'; const numRuleName: string = '/max/min/'; -const maxDepth: number = 128; +const maxDepth: number = 256; export class ProcedureLogicWorkerPerf extends LogicHandler { filesData: any = {}; -- Gitee From 2a5eb29fb3bfe9998ab393de78bd4c9bcb8ff072 Mon Sep 17 00:00:00 2001 From: zhangzepeng Date: Tue, 5 Dec 2023 19:15:42 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E2=80=981.fix:=E8=B7=91=E9=81=93=E6=97=97?= =?UTF-8?q?=E5=AD=90=E6=B7=BB=E5=8A=A0=E5=A4=87=E6=B3=A8bug=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D2.=E6=B7=BB=E5=8A=A0allAppStartups=E6=B3=B3=E9=81=93?= =?UTF-8?q?=E7=BB=98=E5=88=B63.=E6=96=87=E6=A1=A3=E8=B5=84=E6=96=99?= =?UTF-8?q?=E4=BF=AE=E6=94=B94.=E7=82=B9=E5=87=BB=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E8=B7=B3=E8=BD=AC=E6=96=B0=E5=A2=9E=E5=BC=95?= =?UTF-8?q?=E5=AF=BC=E7=BA=BF=E2=80=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzepeng --- ide/src/TraceRowConfig.ts | 479 ++++++++++++++++++ ide/src/doc/md/quickstart_native_memory.md | 12 +- ...ickstart_Application_operation_skills.html | 6 +- ide/src/doc/quickstart_animation.html | 2 +- ide/src/doc/quickstart_app_startup.html | 2 +- ide/src/doc/quickstart_arkts.html | 4 +- ide/src/doc/quickstart_hilog.html | 2 +- ide/src/doc/quickstart_hisystemevent.html | 2 +- ide/src/doc/quickstart_memory_template.html | 56 +- ide/src/doc/quickstart_native_memory.html | 20 +- ide/src/doc/quickstart_parsing_ability.html | 8 +- .../doc/quickstart_schedulinganalysis.html | 2 +- ide/src/doc/quickstart_taskpool.html | 2 +- ide/src/figures/Allmemory/snativeheaptab.jpg | Bin 0 -> 24350 bytes ide/src/figures/Allmemory/ssampletab.jpg | Bin 122502 -> 62784 bytes ide/src/figures/Allmemory/sstaaticstab.jpg | Bin 99163 -> 52792 bytes ide/src/figures/Hilog/hilogconfig.jpg | Bin 41510 -> 32692 bytes ide/src/trace/SpApplication.ts | 2 +- ide/src/trace/bean/ThreadStruct.ts | 1 + ide/src/trace/component/SpHelp.ts | 13 - ide/src/trace/component/SpKeyboard.ts | 6 + ide/src/trace/component/SpSystemTrace.ts | 144 +++++- .../trace/component/chart/SpAllAppStartups.ts | 141 ++++++ .../trace/component/chart/SpChartManager.ts | 4 + .../trace/component/chart/SpProcessChart.ts | 193 ++++--- .../trace/component/trace/base/RangeSelect.ts | 6 +- .../trace/component/trace/base/TraceRow.ts | 1 + .../trace/component/trace/base/TraceSheet.ts | 19 +- .../component/trace/sheet/TabPaneCurrent.ts | 1 + .../trace/sheet/TabPaneCurrentSelection.ts | 57 ++- .../trace/timer-shaft/TabPaneFlag.ts | 1 + ide/src/trace/database/SqlLite.ts | 29 ++ .../database/ui-worker/ProcedureWorker.ts | 2 + .../ui-worker/ProcedureWorkerAllAppStartup.ts | 109 ++++ .../ui-worker/ProcedureWorkerCommon.ts | 245 +++++---- .../ui-worker/ProcedureWorkerThread.ts | 1 + 36 files changed, 1364 insertions(+), 208 deletions(-) create mode 100644 ide/src/TraceRowConfig.ts create mode 100644 ide/src/figures/Allmemory/snativeheaptab.jpg create mode 100644 ide/src/trace/component/chart/SpAllAppStartups.ts create mode 100644 ide/src/trace/database/ui-worker/ProcedureWorkerAllAppStartup.ts diff --git a/ide/src/TraceRowConfig.ts b/ide/src/TraceRowConfig.ts new file mode 100644 index 000000000..60e6c73da --- /dev/null +++ b/ide/src/TraceRowConfig.ts @@ -0,0 +1,479 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BaseElement, element } from '../../../../base-ui/BaseElement.js'; +import '../../../../base-ui/checkbox/LitCheckBox.js'; +import { LitCheckBox } from '../../../../base-ui/checkbox/LitCheckBox.js'; +import { TraceRow } from './TraceRow.js'; +import { SpSystemTrace } from '../../SpSystemTrace.js'; +import { LitSearch } from '../search/Search.js'; +import { TraceSheet } from './TraceSheet.js'; +import { CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU.js'; +import { type BaseStruct } from '../../../bean/BaseStruct.js'; + +@element('trace-row-config') +export class TraceRowConfig extends BaseElement { + static allTraceRowList: Array> = []; + selectTypeList: Array | undefined = []; + private spSystemTrace: SpSystemTrace | null | undefined; + private sceneTable: HTMLDivElement | null | undefined; + private chartTable: HTMLDivElement | null | undefined; + private inputElement: HTMLInputElement | null | undefined; + private traceRowList: NodeListOf> | undefined; + + get value(): string { + return this.getAttribute('value') || ''; + } + + set value(value: string) { + this.setAttribute('value', value); + } + + static get observedAttributes(): string[] { + return ['mode']; + } + + init(): void { + let sceneList = [ + 'FrameTimeline', + 'TaskPool', + 'AnimationEffect', + 'AppStartup', + 'HiSysEvent', + 'EnergyEvent', + 'Memory', + 'ProcessMemory', + 'ArkTs', + 'NativeMemory', + 'HiPerf', + 'HiEBpf', + ]; + this.selectTypeList = []; + this.sceneTable!.innerHTML = ''; + this.chartTable!.innerHTML = ''; + this.inputElement!.value = ''; + this.spSystemTrace = this.parentElement!.querySelector('sp-system-trace'); + this.traceRowList = + this.spSystemTrace!.shadowRoot?.querySelector('div[class=rows-pane]')!.querySelectorAll>( + "trace-row[row-parent-id='']" + ); + let allowSceneList: Array = []; + TraceRowConfig.allTraceRowList.push(...this.traceRowList!); + this.traceRowList!.forEach((traceRow: TraceRow) => { + traceRow.setAttribute('scene', ''); + if (traceRow.templateType.length > 0) { + traceRow.templateType.forEach((type) => { + if (sceneList.indexOf(type) >= 0 && allowSceneList.indexOf(type) < 0) { + allowSceneList.push(type); + this.initConfigSceneTable(type); + } + }); + } + this.initConfigChartTable(traceRow); + }); + } + + initConfigSceneTable(item: string): void { + let spliceIndex = 1; + let div = document.createElement('div'); + div.className = 'scene-option-div'; + div.textContent = item; + let optionCheckBox: LitCheckBox = new LitCheckBox(); + optionCheckBox.checked = false; + optionCheckBox.style.justifySelf = 'center'; + optionCheckBox.style.height = '100%'; + optionCheckBox.title = item; + optionCheckBox.addEventListener('change', () => { + this.clearLines(optionCheckBox.title); + if (optionCheckBox.checked) { + this.selectTypeList!.push(item); + } else { + if (this.selectTypeList!.length > 0) { + let indexNum = this.selectTypeList!.indexOf(item); + this.selectTypeList!.splice(indexNum, spliceIndex); + } + } + this.resetChartOption(); + this.resetChartTable(); + }); + let htmlDivElement = document.createElement('div'); + htmlDivElement.style.display = 'grid'; + htmlDivElement.style.gridTemplateColumns = '1fr 1fr'; + htmlDivElement.appendChild(div); + htmlDivElement.appendChild(optionCheckBox); + this.sceneTable?.appendChild(htmlDivElement); + } + + clearLines(type: string) { + if (type === 'FrameTimeline' || type === 'AppStartup') { + this.spSystemTrace?.removeLinkLinesByBusinessType('janks'); + } else if (type === 'Task Pool') { + this.spSystemTrace?.removeLinkLinesByBusinessType('task'); + } + } + + initConfigChartTable(row: TraceRow): void { + let templateType = ''; + if (row.templateType.length > 0) { + templateType = row.templateType.reduce((pre, cur) => `${pre}:${cur}`); + } + let div = document.createElement('div'); + div.className = 'chart-option-div chart-item'; + div.textContent = row.name; + div.title = row.name; + div.setAttribute('search_text', row.name); + let optionCheckBox: LitCheckBox = new LitCheckBox(); + optionCheckBox.checked = true; + optionCheckBox.className = 'chart-config-check chart-item'; + optionCheckBox.style.height = '100%'; + optionCheckBox.style.justifySelf = 'center'; + optionCheckBox.title = templateType; + optionCheckBox.setAttribute('search_text', row.name); + optionCheckBox.addEventListener('change', () => { + if (row.folder) { + TraceRowConfig.allTraceRowList.forEach((chartRow): void => { + let upParentRow = chartRow; + while (upParentRow.hasParentRowEl) { + if (!upParentRow.parentRowEl) { + break; + } + upParentRow = upParentRow.parentRowEl; + } + if (upParentRow === row) { + if (optionCheckBox.checked) { + chartRow.rowHidden = false; + chartRow.setAttribute('scene', ''); + } else { + row.expansion = true; + chartRow.removeAttribute('scene'); + chartRow.rowHidden = true; + } + } + }); + } + if (optionCheckBox.checked) { + row.rowHidden = false; + row.setAttribute('scene', ''); + } else { + row.removeAttribute('scene'); + row.rowHidden = true; + } + this.refreshSystemPanel(); + }); + this.chartTable!.append(...[div, optionCheckBox]); + } + + resetChartOption(): void { + this.shadowRoot!.querySelectorAll('.chart-item').forEach((litCheckBox: LitCheckBox) => { + let isShowCheck: boolean = false; + if (this.selectTypeList!.length === 0) { + isShowCheck = true; + } else { + if (litCheckBox.title !== '') { + let divTemplateTypeList = litCheckBox.title.split(':'); + for (let index = 0; index < divTemplateTypeList.length; index++) { + let type = divTemplateTypeList[index]; + if (this.selectTypeList!.indexOf(type) >= 0) { + isShowCheck = true; + break; + } + } + } + } + litCheckBox.checked = isShowCheck; + }); + } + + resetChartTable(): void { + if (this.traceRowList && this.traceRowList.length > 0) { + this.traceRowList.forEach((traceRow: TraceRow) => { + let isShowRow: boolean = false; + if (this.selectTypeList!.length === 0) { + traceRow.rowHidden = false; + traceRow.setAttribute('scene', ''); + this.refreshChildRow(traceRow.childrenList, true); + } else { + for (let index = 0; index < traceRow.templateType!.length; index++) { + let type = traceRow.templateType![index]; + if (this.selectTypeList!.indexOf(type) >= 0) { + isShowRow = true; + break; + } + } + traceRow.expansion = false; + if (isShowRow) { + if (traceRow.templateType.length > 0) { + traceRow.rowHidden = false; + traceRow.setAttribute('scene', ''); + if (traceRow.childrenList && traceRow.childrenList.length > 0) { + this.refreshChildRow(traceRow.childrenList, isShowRow); + } + } + } else { + traceRow.removeAttribute('scene'); + traceRow.rowHidden = true; + this.refreshChildRow(traceRow.childrenList); + } + } + }); + this.spSystemTrace?.collectRows.forEach((favoriteRow) => { + let isShowRow: boolean = false; + if (this.selectTypeList!.length === 0) { + favoriteRow.rowHidden = false; + favoriteRow.setAttribute('scene', ''); + } else { + if (favoriteRow.parentRowEl) { + favoriteRow.parentRowEl.expansion = false; + for (let index = 0; index < favoriteRow.parentRowEl!.templateType!.length; index++) { + if (this.selectTypeList!.indexOf(favoriteRow.parentRowEl!.templateType![index]) >= 0) { + isShowRow = true; + break; + } + } + } else { + for (let index = 0; index < favoriteRow.templateType!.length; index++) { + if (this.selectTypeList!.indexOf(favoriteRow.templateType![index]) >= 0) { + isShowRow = true; + break; + } + } + } + if (isShowRow) { + favoriteRow.rowHidden = false; + favoriteRow.setAttribute('scene', ''); + } else { + favoriteRow.removeAttribute('scene'); + favoriteRow.rowHidden = true; + } + } + }); + this.refreshSystemPanel(); + } + } + + refreshChildRow(childRows: Array>, isShowScene: boolean = false): void { + childRows.forEach((row) => { + if (isShowScene) { + row.setAttribute('scene', ''); + if (row.childrenList && row.childrenList.length > 0) { + this.refreshChildRow(row.childrenList, isShowScene); + } + row.expansion = false; + } else { + row.removeAttribute('scene'); + row.rowHidden = true; + if (row.childrenList && row.childrenList.length > 0) { + this.refreshChildRow(row.childrenList); + } + } + }); + } + + refreshSystemPanel(): void { + this.clearSearchAndFlag(); + this.spSystemTrace!.rowsPaneEL!.scroll({ + top: 0 - this.spSystemTrace!.canvasPanel!.offsetHeight, + left: 0, + behavior: 'smooth', + }); + this.spSystemTrace!.refreshFavoriteCanvas(); + this.spSystemTrace!.refreshCanvas(true); + } + + clearSearchAndFlag(): void { + let traceSheet = this.spSystemTrace!.shadowRoot?.querySelector('.trace-sheet') as TraceSheet; + if (traceSheet) { + traceSheet!.setAttribute('mode', 'hidden'); + } + let search = document.querySelector('sp-application')!.shadowRoot?.querySelector('#lit-search') as LitSearch; + if (search) { + search.clear(); + } + let highlightRow = this.spSystemTrace!.shadowRoot?.querySelector>('trace-row[highlight]'); + if (highlightRow) { + highlightRow.highlight = false; + } + this.spSystemTrace!.timerShaftEL?.removeTriangle('inverted'); + CpuStruct.wakeupBean = undefined; + this.spSystemTrace!.hoverFlag = undefined; + this.spSystemTrace!.selectFlag = undefined; + } + + initElements(): void { } + + connectedCallback(): void { + this.sceneTable = this.shadowRoot!.querySelector('#scene-select'); + this.chartTable = this.shadowRoot!.querySelector('#chart-select'); + this.inputElement = this.shadowRoot!.querySelector('input'); + this.inputElement?.addEventListener('keyup', () => { + this.shadowRoot!.querySelectorAll('.chart-item').forEach((elementOption: HTMLElement) => { + let searchText = elementOption.getAttribute('search_text') || ''; + if (searchText!.indexOf(this.inputElement!.value) < 0) { + elementOption.style.display = 'none'; + } else { + elementOption.style.display = 'block'; + } + }); + this.value = this.inputElement!.value; + }); + } + + initHtml(): string { + return ` + +
    + Display Template + +
    +
    +
    + +
    Template Select
    +
    +
    +
    +
    +
    + +
    Timeline Details
    +
    +
    + +
    + +
    +
    +
    +
    +
    +`; + } + + attributeChangedCallback(name: string, oldValue: string, newValue: string): void { + if (name === 'mode' && newValue === '') { + this.init(); + } + } +} diff --git a/ide/src/doc/md/quickstart_native_memory.md b/ide/src/doc/md/quickstart_native_memory.md index d293018d1..f4898b246 100644 --- a/ide/src/doc/md/quickstart_native_memory.md +++ b/ide/src/doc/md/quickstart_native_memory.md @@ -53,14 +53,14 @@ Native Memory是查看内存的分配和释放等情况。 Statistics的Tab页,主要显示了统计明细类型。 ![GitHub Logo](../../figures/NativeMemory/Statistics.jpg) + Memory Type:内存的类型。 -+ Exsiting:框选区域内申请没有释放的大小。 -+ #Exsiting:框选区域内申请没有释放的次数。 ++ Existing:框选区域内申请没有释放的大小。 ++ #Existing:框选区域内申请没有释放的次数。 + Transient:框选区域内释放的大小。 + #Transient:框选区域内释放的次数。 + Total Bytes:框选区间内申请的大小。 + #Total: 框选区间内申请的次数。 + Peak Value: 框选区间内内存申请的峰值。 -+ Exsiting/Total:框选区间内剩余的内存比上申请的内存,其中浅紫色是框选区间内申请的大小/整个时间轴(申请+释放的总大小),深紫色是框选区间内(申请+释放)的大小/整个时间轴(申请+释放的总大小)。 ++ Existing/Total:框选区间内剩余的内存比上申请的内存,其中浅紫色是框选区间内申请的大小/整个时间轴(申请+释放的总大小),深紫色是框选区间内(申请+释放)的大小/整个时间轴(申请+释放的总大小)。 Call Info的Tab页,主要显示了调用树详细类型。 ![GitHub Logo](../../figures/NativeMemory/CallInfo.jpg) @@ -82,15 +82,15 @@ Snapshot List的Tab页,主要显示了各时刻内存的增长的差值。 + Timestamp :时间戳信息。 + Net Growth :自从上次Snapshot的增长量,是计算的分配和释放的。 + Total Growth :自从上次Snapshot的增长量,是计算的每一次分配的。 -+ #Exsiting :仍然存在的内存数。 ++ #Existing :仍然存在的内存数。 ### Native Memory的辅助信息功能 在Call Info和Native Memory的Tab页,点击选中某一行,右边画红线处会显示出该行调用栈的树结构信息。 ![GitHub Logo](../../figures/NativeMemory/nativecallstack.jpg) ### Native Memory详细显示的过滤功能 -点击下方的All Allocations可以对Allocation的lifeSpan进行过滤,有三个选择:All Allocatios,Create & Exsiting,Create & Destroyed。 +点击下方的All Allocations可以对Allocation的lifeSpan进行过滤,有三个选择:All Allocatios,Create & Existing,Create & Destroyed。 ![GitHub Logo](../../figures/NativeMemory/lifespan.jpg) + All Allocations:所有的内存。 -+ Created & Exsiting:创建且被存活的内存。 ++ Created & Existing:创建且被存活的内存。 + Created & Destroyed: 创建且被销毁的内存。 点击下方的All Heap&Anonymous可以对内存类型进行过滤。 ![GitHub Logo](../../figures/NativeMemory/AllocationType.jpg) diff --git a/ide/src/doc/quickstart_Application_operation_skills.html b/ide/src/doc/quickstart_Application_operation_skills.html index 845473d56..9942e0170 100644 --- a/ide/src/doc/quickstart_Application_operation_skills.html +++ b/ide/src/doc/quickstart_Application_operation_skills.html @@ -808,10 +808,10 @@ 导入so以后,在搜索框中输入libnative_hook.z.so,会发现符号化数据已经更新。
    GitHub Logo

    -

    网页连接文件打开接口

    +

    网页链接文件打开接口

    - 网页连接文件打开接口可以在网址后增加文件地址,打开后直接打开trace。
    + 网页链接文件打开接口可以在网址后增加文件地址,打开后直接打开trace。
    接口的url路径如下:
    GitHub Logo

    @@ -866,7 +866,7 @@

    单个泳道图显示为多行时可折叠为1行(收藏和非收藏)

    - 单个泳道图点击会将泳道图折叠为一行,折腾后的字体是蓝色。
    + 单个泳道图点击会将泳道图折叠为一行,折叠后的字体是蓝色。
    GitHub Logo

    已支持的泳道图按照模板分类显示,NaitveMemory,Hisysevent,应用内存等

    diff --git a/ide/src/doc/quickstart_animation.html b/ide/src/doc/quickstart_animation.html index 93c949f5a..29ab5dfdf 100644 --- a/ide/src/doc/quickstart_animation.html +++ b/ide/src/doc/quickstart_animation.html @@ -801,7 +801,7 @@
    • -Animation effect:动效配置项的总开关。
      +Animation effect:动效配置项的总开关。解析时请打开对应的Flags标记(Disabled切换为Enabled)。
       
    diff --git a/ide/src/doc/quickstart_app_startup.html b/ide/src/doc/quickstart_app_startup.html index ce0107c86..36fbd7096 100644 --- a/ide/src/doc/quickstart_app_startup.html +++ b/ide/src/doc/quickstart_app_startup.html @@ -803,7 +803,7 @@
    • -App startup:配置项的总开关。
      +App startup:配置项的总开关。解析时请打开对应的Flags标记(Disabled切换为Enabled)。
       
    diff --git a/ide/src/doc/quickstart_arkts.html b/ide/src/doc/quickstart_arkts.html index 9edcb0f5e..f88fdfd48 100644 --- a/ide/src/doc/quickstart_arkts.html +++ b/ide/src/doc/quickstart_arkts.html @@ -797,14 +797,14 @@

    Cpuprofiler的抓取配置参数

    - 打开Start Ark Ts Record总开关下面的Start cpu profiler开关抓取cpuprofiler数据。 + 打开Start Ark Ts Record总开关下面的Start cpu profiler开关抓取Cpuprofiler数据。
    GitHub Logo

    Cpuprofiler展示说明

    - 将抓取的cpuprofiler文件导入到smartperf中,查看Ts层耗时长的函数和阶段。 + 将抓取的Cpuprofiler文件导入到SmartPerf中,查看Ts层耗时长的函数和阶段。
    GitHub Logo

    diff --git a/ide/src/doc/quickstart_hilog.html b/ide/src/doc/quickstart_hilog.html index 7c9528d1a..949612296 100644 --- a/ide/src/doc/quickstart_hilog.html +++ b/ide/src/doc/quickstart_hilog.html @@ -799,7 +799,7 @@

    Hilog的抓取配置参数

    - 打开Hilog开关抓取taskpool数据。
    + 打开Hilog开关抓取Hilog数据。
    GitHub Logo

    Hilog展示说明

    diff --git a/ide/src/doc/quickstart_hisystemevent.html b/ide/src/doc/quickstart_hisystemevent.html index 609629f5d..707ace392 100644 --- a/ide/src/doc/quickstart_hisystemevent.html +++ b/ide/src/doc/quickstart_hisystemevent.html @@ -835,7 +835,7 @@ System Event泳道: 以条状图显示,红色代表后台任务(WORKSCHEDULE
  • -Power泳道:应用各个子类的功耗柱状图、折现图以及应用各个子类绘制的图例,鼠标的悬浮可以显示出各个子类功耗的具体值。
    +Power泳道:应用各个子类的功耗柱状图、折线图以及应用各个子类绘制的图例,鼠标的悬浮可以显示出各个子类功耗的具体值。
     
  • diff --git a/ide/src/doc/quickstart_memory_template.html b/ide/src/doc/quickstart_memory_template.html index ebbe64ce5..4b4f3cf39 100644 --- a/ide/src/doc/quickstart_memory_template.html +++ b/ide/src/doc/quickstart_memory_template.html @@ -1126,8 +1126,8 @@ MinSize:Gpu内存的最小值。

    VM Tracker下的smaps泳道图的点选和框选功能

    - 点选和框选Dirty,Swapped,RSS,PSS,USS的5个泳道图中任一个显示的都是一样的内容,会显示Smaps Statistic和Smaps - sample的tab页。 + 点选Dirty,Swapped,RSS,PSS,USS的5个泳道图中任一个显示的都是一样的内容,会显示Smaps Statistic,Smaps + sample,Smaps Comparison,Native Heap的tab页。
    Smaps Statistic的tab页展示。
    @@ -1304,10 +1304,60 @@ Protection: 内存块的权限(读写执行执行)。 >

  • +

    + Native Heap的tab页展示。 +
    + GitHub Logo +

    +
      +
    • +
      +TimeStamp: 时间戳信息。
      +
      +
    • +
    • +
      +Total: 该时间点Smaps中type为NATIVE_HEAP的Size。
      +
      +
    • +
    • +
      +RenderServiceCpu:渲染框架数据,计算规则为该时间点上memroy_rs_image表中type!="pixelmap"的所有项累加Size。
      +
      +
    • +
    • +
      +SkiaCpu:渲染框架数据,取该时间点memory_cpu表中total_size的值。
      +
      +
    • +
    • +
      +GLESHostCache: GLES-CPU缓存,取该时间点memory_profile表中total_size之和。
      +
      +
    • +
    • +
      +ProcessCache: Total-RenderServiceCpu-SkiaCpu-GLESHostCache的值。
      +
      +
    • +
    +

    + 框选Dirty,Swapped,RSS,PSS,USS的5个泳道图中任一个显示的都是一样的内容,会显示Smaps Statistic和Smaps + sample的tab页。 +
    + Smaps Statistic的tab页和Smaps sample的tab页展示(同点选)。 +
    +

    VM Tracker下的GPU泳道图展示

    - smaps泳道图分为GL,Skia Gpu Dump Toal,Skia Gpu Dump Window,Skia Gpu Memory泳道图。 + GPU泳道图分为GL,Skia Gpu Dump Toal,Skia Gpu Dump Window,Skia Gpu Memory泳道图。
    GitHub Logo
    diff --git a/ide/src/doc/quickstart_native_memory.html b/ide/src/doc/quickstart_native_memory.html index 34526429a..be0ade86c 100644 --- a/ide/src/doc/quickstart_native_memory.html +++ b/ide/src/doc/quickstart_native_memory.html @@ -891,12 +891,12 @@ Memory Type:内存的类型。

  • -Exsiting:框选区域内申请没有释放的大小。
    +Existing:框选区域内申请没有释放的大小。
     
  • -#Exsiting:框选区域内申请没有释放的次数。
    +#Existing:框选区域内申请没有释放的次数。
     
  • @@ -926,7 +926,7 @@ Peak Value: 框选区间内内存申请的峰值。
  • -Exsiting/Total:框选区间内剩余的内存比上申请的内存,其中浅紫色是框选区间内申请的大小/整个时间轴(申请+释放的总大小),深紫色是框选区间内(申请+释放)的大小/整个时间轴(申请+释放的总大小)。
    +Existing/Total:框选区间内剩余的内存比上申请的内存,其中浅紫色是框选区间内申请的大小/整个时间轴(申请+释放的总大小),深紫色是框选区间内(申请+释放)的大小/整个时间轴(申请+释放的总大小)。
     
  • @@ -937,7 +937,7 @@ Exsiting/Total:框选区间内剩余的内存比上申请的内存,其中浅
    • -Symble Name:每个内存分配的调用栈。
      +Symbol Name:每个内存分配的调用栈。
       
    • @@ -1009,7 +1009,7 @@ Timestamp :时间戳信息。
    • -Net Growth :自从上次Snapshot的增长量,是计算的分配和释放的。
      +Net Growth :自从上次Snapshot的增长量,是计算分配和释放的。
       
    • @@ -1019,7 +1019,7 @@ Total Growth :自从上次Snapshot的增长量,是计算的每一次分配
    • -#Exsiting  :仍然存在的内存数。
      +#Existing  :仍然存在的内存数。
       
    @@ -1032,8 +1032,8 @@ Total Growth :自从上次Snapshot的增长量,是计算的每一次分配

    Native Memory详细显示的过滤功能

    - 点击下方的All Allocations可以对Allocation的lifeSpan进行过滤,有三个选择:All Allocatios,Create & - Exsiting,Create & Destroyed。
    + 点击下方的All Allocations可以对Allocation lifeSpan进行过滤,有三个选择:All Allocations,Created & + Existing,Created & Destroyed。
    GitHub Logo

      @@ -1044,7 +1044,7 @@ Total Growth :自从上次Snapshot的增长量,是计算的每一次分配
    • - Created & Exsiting:创建且被存活的内存。
      + Created & Existing:创建且存活的内存。
       
    • @@ -1054,7 +1054,7 @@ Total Growth :自从上次Snapshot的增长量,是计算的每一次分配

    - 点击下方的All Heap&Anonymous可以对内存类型进行过滤。
    + 点击下方的All Heap&Anonymous VM可以对内存类型进行过滤。
    GitHub Logo

      diff --git a/ide/src/doc/quickstart_parsing_ability.html b/ide/src/doc/quickstart_parsing_ability.html index 48f39267b..9b4bba0d2 100644 --- a/ide/src/doc/quickstart_parsing_ability.html +++ b/ide/src/doc/quickstart_parsing_ability.html @@ -800,8 +800,8 @@

      超大trace分段打开,超大trace按照固定大小切割,分段打开显示

      - 超大trace分段打开是对现有配置抓取的同一种时钟源数据源的。也就是配置命令下发的抓取有效。Htrace数据按照端测切割的大小的分成多个文件,并将不能切割的hiperf、ebpf、arkts的数据单独存储。IDE通过将这几种源文件数据存储在IndexedDB,并调用trace - streamer去进行切割数据,并在IDE测过滤筛选出切割的数据进行展示。 + 超大trace分段打开是对现有配置抓取的同一种时钟源数据源的。也就是配置命令下发的抓取有效。Htrace数据按照端侧切割的大小分成多个文件,并将不能切割的hiperf、ebpf、arkts的数据单独存储。IDE通过将这几种源文件数据存储在IndexedDB,并调用trace + streamer去进行切割数据,并在IDE侧过滤筛选出切割的数据进行展示。

      超大trace浏览器用户数据目录配置说明

      @@ -810,7 +810,7 @@
      D:\deskTop\msedge.exe.lnk --user-data-dir=D:\Edgedata
       	D:\deskTop\msedge.exe.lnk    浏览器的exe执行文件位置(或者浏览器exe的快捷方式位置)
      -	--user-data-dir=D:\Edgedata   指定用户目录数据位置,本地除系统盘外的位置都可以,内存尽量大一点
      +	--user-data-dir=D:\Edgedata   指定用户目录数据位置,本地除系统盘外的位置都可以,内存尽量大一点
       
      浏览器exe或者exe快捷方式目录和名称不能有带空格
      @@ -850,7 +850,7 @@ Single file max size: trace文件分割的大小。

      web端支持已打开的trace文件转换成systrace,并可下载

      - 已打开的trace界面,增加trace conver按钮,支持将htrace和row trace转为systrace。
      + 已打开的trace界面,增加convert to systrace按钮,支持将htrace和row trace转为systrace。
      GitHub Logo

      diff --git a/ide/src/doc/quickstart_schedulinganalysis.html b/ide/src/doc/quickstart_schedulinganalysis.html index 32dca3547..d22311103 100644 --- a/ide/src/doc/quickstart_schedulinganalysis.html +++ b/ide/src/doc/quickstart_schedulinganalysis.html @@ -799,7 +799,7 @@

      Scheduling analysis抓取界面配置说明

      - 打开Scheduling analysis开关抓取调度分析数据。
      + 打开Scheduling analysis开关抓取调度分析数据。同时请打开对应的Flags标记(Disabled切换为Enabled)。
      GitHub Logo

      Scheduling analysis文件的抓取

      diff --git a/ide/src/doc/quickstart_taskpool.html b/ide/src/doc/quickstart_taskpool.html index a0152dfc5..007e0b3d7 100644 --- a/ide/src/doc/quickstart_taskpool.html +++ b/ide/src/doc/quickstart_taskpool.html @@ -797,7 +797,7 @@

      TaskPool的抓取

      TaskPool的抓取配置参数

      - 打开Task pool开关抓取taskpool数据。
      + 打开Task pool开关抓取taskpool数据。同时请打开对应的Flags标记(Disabled切换为Enabled)。
      GitHub Logo

      TaskPool展示说明

      diff --git a/ide/src/figures/Allmemory/snativeheaptab.jpg b/ide/src/figures/Allmemory/snativeheaptab.jpg new file mode 100644 index 0000000000000000000000000000000000000000..34d50b6a0fa5fc26f8e35ba2ed5391b89c7bc7fb GIT binary patch literal 24350 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 literal 122502 zcmeEv2UrwY)^;OV5kzuq6p+vaL6A&?NR}))NfH48$(dFVQ6vZm2qFlGWRRR`5y=9Q zCFh)T>hKrNI5NA=ezUW?-?z{6i&j6?eXCF1d%}C(b8l5O`U`p-bWTA=UIv7LfdO&{ z{(;a#ASnAA~32F<#5BB~$NQXS!nQ=!buroPv^yn)wn7D;ql> z|5X7&Az`WO(lWAg@(LO^HMO*LboI>4EpA)hv9fk@c5!uc_we+881N|Y@sps4$mdbf zF)w1{l2hKKzD-Nd$Sf!$j2p&A5nxah<}#!oP8`$@84T1@Tl%c1|GhgxL&#qJH#DB$)iE_YG}}z zU%rS29e>k(gcN3OQVFes7TFxoH~&p5_~ci$Lpo)Div6hsQ2l?MCwxGIDEQpmhn6X( z%l*Cyweu4`G|5@(;W?J%xYv!Ibu9JfSmXm!Ycdvhk}%- zjv7QH8Wfa*B1e6VcQojifM-QD)w#mlVR!mB#Ug*-2%WH>M}xMB;9tL)N0S`391K81 z;BE+vap3oj|BP5`gnnlVhji4Iy-1nn)XhCfS)Fd~Zzuo3B>c{bj*Y8(uONkliyA;lUGvfFEX1OsY{68g6&H(c%igvl{_8+N`@@OgCLMqvJM3Js#qqdl36zVuJ71_x0rQ#8_A9^=e^ zMW6Y7Ip>=`p+TlKA_onVZP z|0g>91_s1yy6S*2msgZAiv7Pa&;1^LGDs#zL(Vbi8eg5N3@{R_*>RuwFROK=CP#yr zczuHQqbY}qj|pPN*#9*K8Us4x!YHUQOmkzenkpU5`)>=4kQ%N#U2IZj-j!v|_y9;N zh;!d*IfeAwp9-G%S||UP<>h|B#=&j7kl9hE`^QP;zXAdQVq8u0Y0J0XC*F3b*lFje zck227GI9O~Tv3Y6ip{1=P$xOMA`I^=&gRrIb#VlhIkY^!sWlSW?H`tExDiZG*F~{> zl^oChg+*eU<3(_yhQZqTC}WG3wSDSLinJB3Y=@g_(#|g;RV81yew0KI`8$5S9S*RXcMg$Qq6J@0-Arz=51By?2S!( z^wwAHMpjW=ZYF5D*V&Y+>-)O9Eo5+jb4jnAQ@130_R70NiIFR{x%~}S&)e)p4+g}W zMi&3r22|p`nXMgSSVGwD8*+}p3HFhqexkkSYxVOWh#D&ATwOV(j=;*A`s-R|#oUW1lV+PC*zAIkazI8P=Mn~@pJPuFm%R1dTOtSFu zDj{4CZ)QrTqVcE&1^X&Znvg#)f+L{Q%-8I8`x+@ROhH(Y?@zrcD@kZ~^_#_Kh!x*< zOwyvYeCDyBPZ2)vdg!nB<>_1mRTTN8{JA%8E}z}R#+ID+FWaVdYSf%kqHdvsY4!1E z+?F$Ejn-Pftjk3!6D!0pfqTsXg=6tVK~2dnF;8U+Te@gxa4heD-a*=Rx8}55N>|rz zopwdUHb;b_IlQ7o=BS*R#>q`I*taNT;;e{bH-F_TEt?GUZo6nw{o6OsKf(liD37Ly zIjkuzJ)Mv~^SWUF&ox`lGc5Uw-+Lds^m${Hj4bgDS~1UAvpvXkO#EjYn>g z5WU#7_Cb`EpN&^Me)28+CJ_mS2P3eq==xQ!JHxOUiWvcFwb9-|gW7prnf(@1lL>vlcf2 zjo`euUcIs;ILmpyV~=0qb9&Mu+j8pT8)(v*{Zuj7*vW1YDW8=#ikbuy(Rnq-JuOY> zi;m7$WGz+dYThKcNVEoS(h?m#_xOv|-k3#C(N6RMCre3n1A>Rr+4gC8nC6nMMuTJn zmwpkPMB#;Q20vZQcKg+!u??eFZ{`P!4lV9iMd*Nu_%?I98}5;^ikdqmGzR5OyrObJ z`VJ|1Aflc}v<1h5sBc|&rnX*FyPY3Om9)&pJBSV3kWyJ-(%W<{dJwB3`V~B%S8=ETi%c#T?cFxyp zghVc(K?Le`ZKI78(k`B>;jicA-=>_s=CQhBRu)NeG25hCT&hw~)FGI#JnQWE5o?tt z^TU`cXX!XY7Rm?&4n(fRPtmzA$o3`KR2ReUv7fhVZQU3;oOk55aUiSGJ}=2GdDXj| z3QxNc7dNS1+VJuE(qf$KqvWE>N~nE;vrby1^F4OBrU3yhL86APcC@F|SV?SZ&UVa2 z%|~q0QKxSV`6WJMWyf#Eb(rTBn)pyPT$brMm}9d zWPQm%DyHC2p@^5=NPqD?j#Qm2f^+w*y7ErL@iNt3@q1igO%D3f1iXNLZhu_|7M#qS z7xLeaPistv&qk$24NNlcN5c$QRex~g_NSDh*OLghnR*~UdNEG&w{%iG2@ zvTv+~r%~4<>O9xP3f_S$V;orJ+HrB?Jx@0p-X_|YV(y}{5K!^uavQfDDzrD46WYyI zVB_HDTaB@=GezZ#==X07LkiKLhZS`wat@;ln|8iUPm135Zb5rV7b@v|mV%RWQ(1fV zEBW_UZ?Lz}c=+PVPpqA*O>NAog^au}-MAlfwT$<=)OkUsdrln}bJ3s=x@K<&=ZP1H z4Mi55Zz{Y_5OOHnb2leS|WNn+D6B{E1O zd90`QOmgHG?b)U&XeqLhk+#_~s1o8VlQEr_ zff>bfl8W*%+l(o}i8jyYF%22IZH*z?U#j+Qhq#W`7L(VMRu(lT?r1dUEBOwnXwObOqRH~RA4oEOE1pg;Puo>a>|P~?la&> zKis}ImA!V{Cd7(#ap^*zuBv__hjd#kM)#F!~nCTtr=P2!F_^)Ii_0)LOE>ShFA#%h5}8` ztxYf7u>;X4mD$!h#m|-Sbd^)HRf!2u)^EFA;!h(VT+DWH9pzMlDz8rt)-xJfsejtU z1u+KR9jBd3VoX)5s_LBTq0#6XJ>c^0jbmkga_ah!KRBL;1DD}!R*zGo;7!$ZNyS(X z6xWnXDs#)Ou#%Tc2W$Ab}+hc ziB{PSB{(Ep2?`A=(@+g#_aqT2udyu81Xe`CR(rhRD`I8fTO%`bVu&$RLzXej@^0}F z?qI10;|loBP}r54PcWjl9+}RnNp{(^Yn|AnYFZL%(xjlD+h5WFhVz|%l^c zn8{ff`*QN_($(mKV&$b(G|11&-4zByV9NdO@Oe~y1sar40^SGX0*hR_AEIAnx*5A6 zh>hqH$Iu|q=ij%>?sE1ccHW^u@Askm6&=aH9DJ@y1PVuCBq5)=ph04Hq3hyAD6X(& z{k(%E6Ex_-I&8xwQJOqs#Aj^%+WImI4cf;E{GA|Zz8!onClG~O3oIe``H9SDzXJJB{Qa3PPA2xB{_xWue)_{tKKYZc zQ|SJzFMifXKltff*^cA~Z87HPUcSA<~BNKB>6iF1a%Wv&$ z-!4oNw%(NSA=L_fU~l1)_oX(yd1j!QH#;ZZVIg4v_@DFUK;yQ&VQi1K#-u+ib&(>@ zXEemj{_b>6&5*PKE29ll5GGHCm=--uL zRYBR~+YTR$^QkH&Dqwx<#?dG^XZ_9~agF#ulYM)z!qoY8sf-d?wb=xn%t5jAn5~_2 z!x^W!<{~b6tm#vDH1g25)@%rV*OHP_EvKQep%JBB=ZJxqPrMj$H5n2HNWDDWiqW8) z+RpT-6(l2dP;bxn)h1ryQtzT6Rqr~jXUey{gH)(fD(hZZrQ)1Bs;f9$5i1-mWKE6;*0AMl zm>w)V9X&{vFew=4KCUge#oXR|I8JhS^QMNWhz(?*2)N#FF`9a2=T%#lWJ$}2omsi_ zOG@=hsuEVJ_IqN&o7Q`M5n(tUZmQ6M@nEGA3GZYoN1E=9+)F_-hncf;HI*oG0hcjg zwMc*C#$P^b-E;8Qt0WM$=Jg-mrwPwm^E(N*u&23_G@rD|%&anJQ^)h)~KDn2XB z^tjIVoWduAG;&1sl$z%A;jeAU?4`SElq9IBAS5)8Oe(2C3KDikgDm$0xuH4boS5f zKdb|S)V#F%D)3eV^k`b++m7}FWGNb?j0S=Car2Q;NHnMpg}=F;nwK8%>!Iq%1fqi} zFmjU(4YGrE!y8c`cmW)~533b7NUlja68%M@+O9ivE*Q4glyc;RdWC|nV;(_(dFVg{ z$xI7m5n2e$QHz?PK{e7~OMjF*Fz@ai1TBRwi~(1Af}lU;P5;#2f6!kRY?XbWH~d7h z`b$en33qa8NMC3h>bAR0V(|7;=!^Gq&!1SA6RQo-*f%@ptzM>lSHh4 z%XbwFgl#|-mbnxVi>xT%u9h@d7y^W90eU_GEaV(G1|5biufsYh(V(?(*#Tf#D}e_M z8oL;_(sAgv56oE-E$6MF!0Re8ta<6EZ$t3;HM;*mV(`#=oEu-oBt79ANNtg>8~0B6 ztcEQA6*MruVa662*$$=O@OBX6w%WhzScJCeDdB#P4*TU``QUn1T z$KBNi?!qM6XK8(|-2?j#fW*Hk0ro4f{bu-bX&>3&0PW9;3z`&U47(`!U>N$)v-1ZU zI!m@g5oHVDAYiTyl@j-u~+6aMZ;?v72i13qEF6Zvf@ zaeHk8SW*QK7>^;KcNTgy z{)2x0b3*?E{Z#%Ky=)G^#yN2{4Lr^cxn!s`>Axr3{#^8?f8_B=ifIYEqw4TqX~!F* zt!B3~W?#BLr56D4vO`zsC{Vt40SHe`LjuLc+*g7W6J0AJoCt8K*-XeH4|XN%Mb^iR z3@fDH;)Cs1jba%8Yd)7$c|?~}smS_>pBCp9s15whm5JEp4LiPO#CmBT*0|7+d^dxE zIoi!)N3z1QVENNh7wLmvpR=l3$vgO(X_zhYql41EW+mT0$VxH4LNnR71o9U>mHk0= z*F;$y+uLFpjgXuo;%n_ggNetaQoWVbE%9p?a)S#a*{U zl|?kOCzT8}03JfS^+D}nxrK(Y%07!fkQO-3k>NIlg(p_9`Tj~p$bO4C=YP$>ZN2u} zNSs+HBuehYroRYoDaTa5>SkG9$32z0e!j(VDPu$-aCih?B@JZ2lT9+1)uBJu|z6bKvH2?!VmmgWRwF zjl7@wmkMdq;iWju)U8@}kgCc3r=s1u-CoB&Ml4!!PCH7`8$O;WqGl{JXrrgJ)1qHX z$qSV*t+)A>F<3pi^}B(i390Vh&ZCYw_@iq6uLBOFw5SHQsP=s?%z93S)L*CcYI|Kc zWuWI41`VGMe&kAymW^=NyK#5uKFDP!LqokPzsGjDSPk>(TL^Z~X*J#V?G4wIyMxD9 zg&OT9$=c!|SI5)_b`QAo_;&p8cOkM|qQ&puKa0G7ASPCSv(H=mt(CB5{iLDZaFxo; z0o%RTF-_QBn^z)u1|PgE(o{55|FE4rIHs@M9?&Dro6k;&Pbr2mC0@)sEU|Z9KfAN2 z^S;sL_XYl+!+UPuX9lhU2mO;9X6SzWQx?BBvKUdhIkmWDTUu3(dYybte2N361y7jd zbh0p-1oKq)W6+?BPH0g7NGU2rZ)@!wtf@L3){leI917f5VF6#tlDy+)T}6bMa^Mg+l3n1N~ho}4Hb#4MZy#-v!crH1Jo$wi;Ow1=6;z@2+ zIlQ&^HZnroaSFGQW@?e@#j=%AQEw$A#bl&aCefe+Lh#{ianxH_lU@g^G7a?*Qo>^p z*xr}H|JX{PeDS%Ov;+A1aWBa}xYxh1!NVjzO8R^hx4PuN5rcR{f+{DPwXp_M)yBdw zXU%lwW>Lcw_B&Z)!`hjlQ8VOF0MvjQ%uxFvXvd)|i@4%)OAQq;{b(?keJs;#KhDE; z+cJW}{N8(W>Pej942%aJT)5S)2^@gJ2ol$FJZ4-z%QtG&eX?ZjD{%e1ok*y{+5Uu} zP{;%SZvN6O}(s(I7@99P!C=ue|-Em&h%|l2>iwCV33196SptaWDuz80MF+ zx~^gGRGAzEd3<<$s{$yO=%aAdN=+%Rl+#7_DG+_Uwuh0!B>cPP9Y8Z-ht%7HE?w$cES%3%l}5%?0r{9+ zr&*Kl3$2k4x7nJINHJdE_Pe>0D|=+Gfd(ZGz=RjQtpJ~xhb^UT=h9cqzZrKI3XpH8 zlut-`Be!Km9wAr%DjEC9s`ZL$Cv+Ou0u3_IKF~aziC*5#uu&F&AWf>yclyy9N;C}( z%C$vgT7Tcq$f@Uyosp3p_H|uaGPLy5DI8g4TCY}e+!36yR9wgMP|-@l?U_cSgih zoZF05Uuu+wDwgX~y=O=$o{yRtltl!rz?NR;sihe*^#*S?E2u_|>;Q7#iCsSS-mne$ zSn(nCv`y}}osyXMVJ{nDRdPEo?e}*Ak@YA|PHDiq=z(i}%it}kxtDxsT>-1BUd{#s zA=!inM7?y*V(kVDaX$>{tXBa$FSKD?8cNN4_q;#s{tM4&x%DJcga=Om(^y7wJ+Sk@a6fv*uZ zomuVPK=59ehf;4_Ll9D}(1%DsLN<}y@ts3k_QXJcJeQD*Dul;7{m4b*zxxEZ{y7H5 zI18VJphl4@3P2|w9s-^L_?&*j*v5EZjWH-s ztqV3y0vuvc@8RMZ3Oq}P;id86Eaa|C(^dgI)F@z(HMv~n?r~q5HnnRm;DUL z@PB6O!GG$=0&Ie}P8+DJq^1dN~S(jkSaf$jxvRf zka|dL;kd-b{&}|E4?fgi04X?R4enzoai9bnwx5L*=3Z$)gEqD-QByD;z0Uo1jymKB z0)8c0W#{P*+0r>!W0mnL(TtID;u6Ioq>lj&3Uh}KgIkI|It%gU6>l;DN_(+;3a}jB z92%sG1}SW-4^eizk&v(!%{ugp1`Mh(V$iC&75>^*;l~bH`t!f?i2|1 zE!Vn2tBp`QfUT)n5RaDOO9g0<@b;m5NGFx?`phDLS+_hN+~kKJoC5r!pB$y>n{ET! z#Ht2H%!$Zobhgyqcigsoq3tjZKfqN1ECx-zw=?X{jgssJj#pVQjH&K z)h6D)0C+2gktOgfize4KU^!qO(hd2vbBxL(Xb>EUZ6CNFJ9|5^&ge}IFwyu737Cn_mJe#$@y}_0Jf<2e|yeV|1D&02?j! z0a`InF|_E}sb;xRY`dj5k~7jQ6@HpM9%q|F4&*l7*Si{(X3czdCm^Tu#=|Qg@=C=V z!t3R2EN#qi!!2#kRx!-AKDzug@%7uH(wKu`CHpy)mgtriMwP%6KO@7UHPIZIv+vaa z({<)))#Nu0**cn(r<3}(L0Vf@ecZI2)vqdLMb@HjC|nO|#mY4)7&`0xWQ2+Kg$uujOJx z(BmXc8B&b*q|Ri4z|9$TDwSXbu zPjqugC;nN@{=j|RiP^-DVM!zI5R@bdtltSZXO44J+y3v~c4$vorun0=0ANcO23}qh zV%7uCbfSgswAnyz0P>0xk!~tTJgvN^fRY4ZOL2W#KyY2KfgY|V9-hmcN8q+;1DV=4 zEfXMAAADGkZ>Q15o#H+qU_m;9KlOVUfP>-FmlJoIU{~~2_uC0t_rX`rH=>{`@Fk$S z<1xw=)_$%7JR|~HigYoah4eNmWXsIgvG1D$I&(^R2gt*CGTCteYDOLQCuk?_7osG1 zVKv2bQTa}KO_p=f;oN=q7YDhVK( zVL&mp^b*D%ck+#mgW_!uDW9pG+|pXG=h}R6v%n}+Z^@f@FBkRHFv=IldleTs$zt*q z#ei1;#ZILDZT77(;7XPzU*kQB1Far$#`aHWkpC8|6?l^ZxL70CuUe+6QVwvKY9No1 zE%NIe<7+MVF%OF0IdwcnD3Awy`{!-Kb1Q*8&#!xf#y}>aJI*Aw@Top9Ao^x8St-J^ z?knAhE{olE7&zv8AKrNz0|}53fM4>`EZk!kJq6wAv|d2S&DFzji~n3h!C(YBJ0|WtEZVnRS`Ofw^wE$@D8dhk3NR!s_fWolP+4rvW#D+Y2$C(+yaD9YEw)p%zB_R7=8;}H;`7b>|Am*MTz;y}^D2tmtQ1e26Lpe^P#q=Ws8vPg~H}I3Cx|Ug>4ch9tZ1k z&N@B0A;M)#*!q}4C;j4JVlcqLU~51HX%zcABH#`E*l~pqMZLp(>{%kP{m6`c{Lw!?`wQi0q%2~M#LakPdO;6KK}J% z^@Hyp>#=hKp+8rZ7y&$Hk6r@}>hORvqd})Z(LqmJUJ15l(V zZ~iJpZ3c?ii`+C`e~o`9y($e@``q+ZM3H*@l>L`fb5BHEwsTP@LW*(&C5a(l zrVLM^V7{QXoUw(}%q0cZL*Gk$YyviLE+ zT$j&p7rIq_e(dn3ru8K3Bym zuHA1%N#O(3GjNN4=(mt(4?soQI9~70h}xv!z`cQFUuc%mw!F&qG)Ew^&*VBwKh_RqapALOI|4fyeAQ|w`+Su7lv#61 zOgq`lAw6o+n?~Ou^n0h;JwF!xu!R(Z^8^#zJ^{s+26y`0D3WHCRu|=OV*+J<8b7Y9 zDKyY5-t_*9}W4_(vO1u zHKErrz4ZTuUUsi7U#uvtuj5Pdz_{PInK@M#XN9?ki8?U;YNU|ZnaOuoax`A?>73-7 zeh@V*MN;*OWC9?*iCSKL%NE)CmE{Z9MDx{_6{V%WeVFnMP2`gGPE1O9e={p-2!=Cz zx18o9JfQLkIAy)q`1}MF)$4SJDLWqAzxUCn6Gi6OuTWaRVOuI)nfn=t{!ZZ*wfvch zb&^y~rQ#&dA7!=jj+;MrR^~jh4SPi3%va*zR`cDo9f@*9mDO%#Dm=SkvG+SRbJ*G> zN8-yW&gZE_b7#~pe5betQ|riw>Kx&X#XZyKaAX&>5xovQN|U zkL{!JjS%PE=;8aq<;UM(!7y%z8P=5oJh#LNU^@wn$M(s6tfdwb1|hlsN-x(cM~UXQ zDYNVE3ewd??_=D*d@{Y4cc?)w{!v$O6m`Ub1oI4-v&wy{FaBK_e!IX40mqIQ{BY4vR<2PR!yO6Hi@Mnx zUjMLG`Qh-JR=yvG3fY7Ch(7?j-{$1<s|&Z^ZviS(`RLnzT4*isTov+K7M!TvVMgsc~SC~0+#HvJZmVpU@}a?KvU zUF^DNsKRq%vQX=r%X|&#tPOn+9u9}Li^;(l0aM#K>^&NKv}K}9>GI`b&GSDZdJvM& zKXg)pvG2u2uVsOLda#Dv8r9+(ZfL5d^aN6upv%VUSckvwF!e-vS_H_trLt~^d_bY|tNa90-wBVA;=?^(@ur_ab zaqs`ehI5_zey9z6o8S#N!g~OirXKsGZTJoOGW8zC+Pj+B1h+_G)7&2if5?q5w{Ufu zv=Z)#C!Wnf<@+XAn-cBsJw?_cvIJ1XZ304@vPgjP>zz5n9zfCrqNL^CKhDQCl;i6K zNxqil{69{6=59ac38y+xNvNo~noB@vw|<>NuUtrRIDBm6SmBmhX3d zOzK!q>1~}T&%(ahEqlOOk!?*kHOz~5l|!N#8fB$mO}ISWU@~KLn#U6Sy+SLz^?5nx z?Qy7c%V0P{6)L|;NPg2Z^7)taEdJ)l^nfh3??*{ef~u|qSP;s9tpWUI(rO&2xS)=} zb*F&dK6af>Za*ytW|j|68y9x~ z^Ua@CaY9)DdF8*zyK~||OP^fW8p<#1=W(FPzoHkl&`pUckKyY5tehI%lm|4o*L7dG zoaTx5+GNFWfFh7Uz#StRiOdQ8TiY-1i^PT@OJN%+N8)3B_D8@Z;FQEUV1e-{26do< zx)glU;5}mlyQo6g7%*)}4J}+j-UckYhT_8@JR$OA*Oico_DceQ+5dkQk0JjeL%?xH zS+?bsL)hw3*LU5%MRkXaWUV{pCFJjl)~j9w+qt-LPVB^z%KE5~V>`PITM!H~9KX4Kf+La}*q*xJek&K0#W-p3czHcW{pEMKYz zIg@JYa<8nM=kal}wS^?v=3K^{p)$p9kl1Ndc(^nuSV$45l~10H(up5_`(gBDVepYE zP5>EJe@XN%>~6v$WzIdCb`Q`E`ap*%+>5bv zOJCI`XHAf4?@@20_j_0Lbj3`&u(;PO;)96DeI|VklGsyVT`4nHp@t57PtaKMJ7+YA z+$!!7-0MxflkKejbDgF#bxUUXTPZcew{{Sa>o(LTJ>u{AX{5a3eG)s2uLyRGw0k;9 zP~6D|?mmAj`yMTU;_En|>+ZM;da*DP_R64-a8f$0cV z_!4l<1Yfr2m#3&}YOsC^l$8XRHV~+p zkNVs$-n#p6%PDy3wo`Y)bBrWuwaUKjEKJs_p5>fi5${g^4{zHBhT;>h_y_OQ--y|D z)bXhiDWmQ%iCj6uz_UW9?{>rMGjYAWm*6Q1b`L$P{a;>IYSMo$E=Q-hwK;{G zqllC9cEoBeU4M~0QkQ`_moZk4AM@CC-Cm!0uI25y8^(XABb}vFJ$1j;u9VgMmiE01 zPQbnR+p`%uO9BGoJiXg)askz^s?ImG5N;Z~Iywb=r_id>aoKg=E0XhV z+_Mg*ONy@pQcMZ)az6l9Mp#umO0h9RzOtWdB|w=Nz9+;jC&f^ht6d*xV5-;<8^%-q z+|@!#vJhc&<>M$_;`0P!-qWj(oxW$Otoo$nA_wi20or6B$Yi zX)LeF)YpXCy6dCG>DGmYy8A(s?YKiFSeyaxLE9!h!F?Q_ggIO(T#4Y&OEzWCuY9E1 z!~m|=h9y8M;g4n~TjX-Mv<59Hb%VWjj~;}#c^Jh`Jk8rzUftezaSNU86h(uI4|KVd zho|k(Ap4%}z1M_Gb%%sGsmAjBsB(UUEtPcWwJ#daoSMafYc4}$@xo1{V|%AD30f*8 z#mkx-=Tu&w%E-+!JFq{lz-}+{ux+J<)CMW}uYL;j ze-NIKvYs2SDYR|NwYXxp$~PpGdo!d^{#0SG^TFc|(pQIPY2OrHEzEVN-#i>p*ELCS z4Gtwk6f*=L(n}k3F0TZBR5|~NLFIDYT>-Or-jcPBI~`pWfhB(OlL>NW9!VWBj0_yH zOa4QA%tge*iuay16e@rsq$Q}{FGTiCiE0}9nl6|<=;F>@5fysx zZ`{N35XNXYr*-e*xrQf)r0y{hH*Qq;5>HS8VrwkIDAOSLuaG$Ll;L8!Vf#$cG zSnpPrdYnD|yxr+lS%afI!uoAW(ok#CBDtPVaZXX`)wd(MW_UbB0l1j2J0{d1n+3`J zyr_!!n%5G2h?A)}}_VAqL zOG<@O#SRVb5dT-z^7aiCV%*pA--QmEnce2co6s4ZxnQ__EdYA;%3yZun}t$}46mz+ zHq68B10o+%`{^!!G&e1Z+>1T8uh|N@_yQ|%+ORTo^=hzNF1PwSdNR3Ud%}_DrDbKo z;&J-k6!d0hJfZ1hSAC5HX>V!U-@Mi7oMqEc<$t3vXyM5v_i;@}72_8KTN-^+3uZKO zpN#l7Bu$#h+cSm3XTlM+xyBmso*nKpR)eYaeX(XXmy!sgqg_8ohr``3pNW2NvPDwt zMelL3np#P`MgPm1d10wn*`qIWcb-=ex}OaWP1{PB34DW}`rOL(ntbR2t^QksIam2c z(fb~&tonH|;{;7AF_Y#4Q@#wCx?z28@&l`meffwPM-@%skOe5zmwxUl;aN7mqbzuIgJeyZc#rR^IH+^Xy<{ zd6Qt0XF`0O@Z3EbRLv5tT~e0OVhz!T*xRJHskx~Z_A~9K_ZGM`?pcV*Iu%Xdm-Vd9 zdw0kCQj4TU`g=)S|4n}9zP_u`u5gRuV!t!KFc(r2jf5&fc0uQmtD}^Y{>nu`f^W9W zu0Oa5Ty*9R5)|L=+uKIqdjUTua2avAvm|wr(XH@E!ss2abh&v?G#6f1D!9^DVLmXE z7gKs0XQY~EMbmEkm4IrrkiGMfVl3lP7$5tL@54~`87_aXfInskOCoyR+ttP@!ngBi zd51T3V%;-RQua z(S6$;Ar~c)Bc9cii0Rd`5}`rjVW05`l@J^&~GaPx_Hbo67J?P>O1V#@@PXmVfnXLzh@30}pp}rLy*! zV1jda+iy#c;5c8P+|YU^r?}^8LkOAmEon-r-7{rPlEIk==G>oM$?BH|-{xhypQkgm zsb*2i_fZhySkB35y)muS8DBzHJKShJHzOJxZdA70w`tJmxPHC+f)#pJlaFjJo<63$nV}9VfjQeE7*K+Uvv-jxyTv`Z6DutMHS_LT4*)(7 zh}xY<8$u?!jSg+u51~P!vjxdrZ~Hk!^5y^;MatsZ_weVQSfGTS~@%V0UpDMEbqI?T0uvekC-Z>=^L>Xf4!29~cqByT(Y zq9oMcj_1LHp<<>YROPTeY^gZd7=NjBuxK#qZBDAJS*Fz*t@c?0Ke?HfRf4p1+Q?%k z6uOkYAJ?r{w80^M@pJvF?dTF2npeV;#+<@Zn93;D(`}}kW6YrSBevD`^G0dH! zH0AO0Rcqd+f8HAj->HD5`s>3CLsdQsyF_|lU)Q;sZ^~S;+0YsAB}f}A)!mhDot`hh zaY5BqD?jua?zILSETl5-jFCTcYEkLs;bwc14xBZ1EeSobVY;;R4sR{j$`r1YWb56& zaQ%7@nDyt_Sl3k%h1^LTIjX(->uXJ2TL^`K=aJijIcmu&N&Yz$W}7o*yVeb$Pi zjkIf)*I3}A9iE1^Ybkx+?uQ;G?iJGI*Am^m3oPmP+aU#=2%$8qd_867CE|>FyKs3o z+B35}c%+E^VOemLRccO=o4O%$m7)WCK!m0Q-TQg`MTzFdzTC8`5#Xv7GE=sa_2G@Bxa(Tvky2ub1AMz7FEBot1h4GHFs$2DXCK*~kt?W)IP6!*_glTO zmH=_qrD0*=z)@Dw`r!$uK(g9xl(ihK8P zgdN&>#)|LG4|2W@xW&my_D*@uRmjp_<3KCqm!CV(qDu>u&U?!3GFD73z~kYo{K@vH zYEBf{p}bT6{r&;b>xm;sYs}R5pLB|1S;S=bHIr0GF>Y90hWV;|f(3Bz-T;q9Zh$e?tBq@f}(Iuj_=7X^Hly5s(+p5?^%P*jCmRabBux~qgof4$b zf?Fs=B5<|$>F;}R>Hh`6?4L`eV=btLGqv+n9Z+PPf9@9{nv-?MBQ7yPGSp=ah=WAm zpw^a-=jmry_F#HH-~H6YPcQfx4}S#<-i*RW!LLBq*d|}FP2Q(xnTzWqOFSMjK9c_R zZ0ZEr{Z4cA1DRe#wouNRks7)${yQW=R=zl#$D8oSSY#VX+@oiJj1x)oGxW zu|eJ5f8+B^H{Vf+ifaEkc@r}l_A6&ApSX&$QcZ6m+RPWl`TD%2#(~AhFAKsJ?Xi>9 zy!^U%TeCwSymOOTs-vsS4|NK&W_C_|HksQWyWp(-2*KrF8~3KdXPCMqT~yy%v^C2s ztCWcEKHZefz1H~cX@|Jpb%D?--E4$RKi`V1T-gzmqs$``4)<;uO2iki_@r>J{^-o5 zLxY_`NQVpTiEvopoZ>69+PxA_nsx@%XRq|91o1dLL@x*taizK5Qa+G|&V8eP$%-EP zONB=_Wkxk=LUn9K-jRC0iDucEjBwL7?pIr0cHP#F(npw=S9Q9a$x^|!K0mr(SEpXG z)x%tnr%@I5Vtp99qs8e#o7EzWoZ~JZ^sM#zLX5VmO@xOP_2sRLLZFZ`kx<9WJn?G4 zkLzrFfsUhS5(1>}4YGU`viCMYgYepmCysK+Q98l9epV4`!UTIp81F?1wnh7$WEBJT zzdq}d?2~(A?XEAI9~)O*G30iUEZZ(55#lOwH0;z>l`_!~HG_Z}(_SLSw?Mn+C9c{C~co_0b@-7UY zazWJ)p;$@J(I?8Ex^J|m-orN|bBZS5=DnLd9G^fEyts}kl1lR{$U78WbFVuM&IZ

      @=aGWN0S%Rvl2 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

      T(G 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%0A0})RP~P^=o1z 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�yC|Q zKOnhwRXVAz3A+w?+2$@VCP7*{PCZ2GVfpTbXMFD5Pd6EpqV=ic2=c?Sk>bY+P^_Fh zUV({@W+F9ailA+$CEN~H zDy{Yz6qbCH*czWVzkA~yxN>R27ppK`Ier9K#DOQfFG#_d67uEW1*?DaJ8sxYr5$03 z;^as(Z5*di8#af{BHc<=%f{9u?SjCnwtPu!m_}A0SEl_IZmx+QLUyzT;8&K*e zu%sMXThHj?BROJbu-B%_!{r@{&28rDC`lTf4Eee)T>-6zxhVQqJ69K6)==3M&PlGS zDlaOD+1N1fnIK}PFR;o=&1UGW9<7I5weKd#e8c@F_3H*t=Uw`+>;5c0u7aN94`&ReN}(rMWK1=b-u#e zi$Sg?QFb;>!z$EC{fKE7a8R|(H2#G{i4Av(hC>HSww}0-rn&IMMD%%uy3ccQwgK=; zO&-y@)(+<-p!>8}GI9FaW#p z0*vr&_h0YyFOspw*%z`L7N<>Q2JBg0om?tjoggoHmEQP{KK$C;eA@wK_TG_|b>pqf zg2P*r(^m@foKz)0RD5)O6WEn#dmU5#5;L+j@tv3V-R(w}W$3DPsgeFLUFglX27v>! zR^;lB#n8XLd|W87E%(+vEmR%dNYbe)aOp+B+Kt2B!fY=3WPfNTOD`NQcL?go_adQz2 zeuOI%nhLg*+rkyvGs;%-g#|9pDj;BE_()a{Ls?&xa(PkhwQ-Y3lc)nai3o+Y)bY#XmQh38WUPJj#0-c9)zja}z%*1V87* zOLB@h|JX@H@NJ&m(puUs9xn&_{#(rsnpX*9ciM5OZ;5|ohIlbkojcPN?vlU-ylx$u(p~6e*h?5iA|LihE= zr>k@-%j4?mNb_s%Sn{>#S+jVNnY%a(B;xfM9!dcOY7o?m`E^37cO-=f z(>}B$_da;q*5-^s(ElW2K>+?1DLXxht+pzl9PFF)b*4`*B651}evs;^2J`;>Jt~uM zH<`f_7`ll@LSfo)ecmc5wQ@vuNFxPJ6SZRVJXLoQ6@N}xv02$G@o|PR1O-bs^7?H1 zx@yCL2*n`m<4su5khY|K+T-Wtp;K^r6Qe zbWBwo`gq5KOa{nK(RdF2;2G^O(sI zX&!>>V$9#c2M5i#i*?(+0C(VG>qZBUZ;rXn{cGp}Q=$L~u?{Oa=>?S$@h{kP*ENfAXfKZk-khEOBDZ zg_U^L(L;Ef_f74!)q}FZvO$W1Snjg&b;_fdj9}`MGmyYk3nM*{2qiih-N&G|{b@cJk{C<9?#_!15ce+^(%iauclGzEyZ7Fk9vt`|zkl`~(j1 z8+n<#59@^bBEmiH2aZ>F-v{=VTri8-hZ)`6$maE3ED2Rk3YUzZ81v27pKGTlaq@Uam-{o*9$h%<%{ls8#BwG9;A8v>K}^ikhhGaN7#Sp%yD6pvXx0 zUl65!@QfSY@Kl;6#Po8ooQr{W!;7)~-xI&^&{ClzkI z`z5HB^7kKoF#RGic1STfU1zCmwfB8zsqB$VIZpn{6vU_LHQArM?4-t9ZxHIckCR#V zO=J(V?CYjC=C8S65-(2T3+c|_ldku(#nxv&3geuR4QvRuw-}FqaxBi#^_*s+M@A zbAE&?`u$j#?e3IY4j&(7c#w5Wu9>A=L+mnC_e*o7f)+Rssa&{33R${#s53b5jPT+h zy9Pgl(7e8A@FRnS(zn@eT2;Z*XCU8d+013@RT(ASAjr?TeU8S!G(t~ox|tmS*rpP@#g8eWA!|_nva^)-pyr&P+$3f zczesJHp6vW6bh8$l;Yl^MGGzNrFe0Q1T7wdYjA0S;#QzQahKo_+@+M_5Fj`dcZUG! zP1n8Wj&=4~d#`=Q8RPs2kzaiFzH>g$oby>5m6zyu&tht%m$(_k{_G)AL`|Pz&hxuL zft`n0cu(ODb?Ip>Sj)y7p`atBu#DS)MhPWxnS3Rnix)k_ilx1lB3*G?SAW`rOJ-FQ z>##8&(<{YoP@?`PwTOj%Igth^>QpL3Tx2c#(M{gD+~h`Gx-qM50blFKuP-HV2EhBU zDnEfgXo(J}Q;0ZMelxp?5{t(-v>;mp)25F!*6;}WNFIALdLS*%3oAt2Ih(8ccc*`R zWB6Jj&VGU6rMzI=jpmAHk@y&0N?Df8blT)EkuY-ab%*o+!dY&Zu2%Vo1OZn5#ZODm)|9&l5Mmg9` zeipve;Li`gS>UtvyXpPRMz#8Yy{Wa~KDnpmndp?ey+Yug(Ha;gS_CakaZmw-siYYX z5O#%HFucb{jbA8_KhX;p2dz7OPVo`UEZI4+6@oCPZN;kB_vL9f>oIU*M4x{eeZAZf z3^oT-KaP3-z7^LZq-lU}_rt{!|DZyR3b*JajiLU~OMDJ8JvKHp-}GV|R)iRD%Wuw- zLiiuFh;4f2n-5&6E#$d5g9S?}h4YXoIOtUxV-^eTvmobQHYlpSQhs9c$t`c*sNpJk z?NIW_`?2;rDBpkvQK}0gxd`{|th$_7yI)VY9H|!N|6yAZy$|fw4MnK;1wI2uZW-#; z&0v~i%3HiR#1ISCz+P1qT4(!oY5GhxcNxeJJQhrKwH8eOVu3l2aqNKk+agvh{m8b^ zf#iVB@W^}Rvp7+uEm8#5@Br9&Z+l6j6Jb%KD?>xjjIMZ>Pl?T()kMe1+xrKNNc=-S zSgJ4JS>mxms%l%SzGX&&8&or zuAj=PDap-nZwfC&C8x5p*f{O*GoKh-i5`21(OHd9Wc7k1oWAWGx#yDkQxP*1Z4JDE5qTlXKEHxE zqT_z>6zP1jBLtV8aS{+}yz?vtI~K-HCy| zW#VgU)YX5kQNU3u#Ye}lcz|*kt`PdY_FW^w)Zc0O+<3OwHAxQgqzF};3;{%8LKT>_I01ba2 zIa6v>=P$wf&T;?q$*Rr%bY$nc>7$#}0TbF9e>-C=j|b6%G5hBc%ae*Hl1dmM&Msrv zIaR888D4kC=PaCnCCHg@_G7S(#$*G|(WL}l55V_U=7j^vbU`@V*5a@HSnNlwcI?G2 zb13{F{jcs>E!dlKV>gA?$zzR%hG|t&6q9&5?K_(eq$jz_T~lGow@u#)^(vHCY)pJ$ zCh04KKqLm-h4+9E;V^sjRGP;!KVyY= zB)=}PtwGLr12{5Frn!H^+7zf_f!rFmukeX;-G(qE9Y`H!5Rr?+270#D40WPk zd*^n`CJJsaygW88Bt1F~H0{^dMNJ)RUOac8SR2g;u9;HVUPC=|8-`1_LKIbA#Tc16 z{-8w!XG0wCB__q?a=_MfY<)yUopUoE8$cx6e8Km=LAMlp~2tgx?r)1FX-I0F>SG&cQP1sFSlk&xUXXAE;uc~nJY9$t7vZ?m(RH2 z#fb2vE1xPUx^%cEYc!4%J0S{cAR+|E>CW=bD%T24RHzj1KJRa_xaqKWJ9sQ2u=7<@ z4WZ8s`3ug_|0WRpS1+TtV8MGov($bFcj?rM+8uk8n|JG($iSjS9N=)L&_Vle5r~e< z3LHrX@F&-=*T2~1nG4?Bdmc@gcAMN7efHXjH`EVforuVEAF(L=wsx8q(x(gePaL{> z^Kl}ZkzU=3Zp6o*6qX)_pto2H42Sn;$EEgDe-$N9+gzw;os~0qG&(Yq?Tm3o8_zja zk{6po2>rL%`7fs4^3$Ybuh4Q@lNGWglML-}4-}Ti`4Vzh1Y6r@qxZ8<;Id<>| zjdFPpitydfdeI0LG<<9bj=&^T96DU6*-y^^+_+TON#V6gtbK8`*S%KFqGC<>?Lvcz zPdG`zc1)O~SEBiL61MBqB??9D2@zY=sX=}yfhEpX4Fp)Xlel14%`C6_mMsyaS`NK7 z!}q;pP!k!6T9a?dCb}2Op=lR81eidscE2m$Q3>(&WTtVS6Xp>4Tv4+F93Bi7St?O- zjuc_jFG$Rc{{6z`If1yV*fhRG_J${I!`{g?&9r7G&SHUI#u{$C+)8alVc8Y7NV3VS zt3?^i7P?$r6ECazAZEuW&JvuHC4~;uM`EqTbEn4IYlD3fZr$WrR2?(ol8rC|V(8iD z+(I2pBEHDe;Bl<&=8dfE0TZ+t-g{ZA^(x#w7a-!Y-bCeg@4a?$z8Qnd_|~4 zLZCm=7w^aURPMbr?1I2c{gmwJGuGzk6j;qX&Z7uQ3*R~(my5BywF{4) z^&+5+48mMG`?M#qk6T}_e)ABB*b4ks@VeliART(oS1nwWn=O5v#yQM8|BKj{@m8$G z!5peR^}=Uk1dz5=3X(y5zEYb+dE7E=Eu~f5-}lD3AnJz0=1IrmhNryQ%wZpFm)|iC z1XI4!9aTFKC6slEL^8{_){XmdMDTYMaC=CH+D(?s7I~pxA2ssf*u}!;wTyU&_I)hnOUeOtX8hpD zA16#5Spw?#zXJSOe}9oUEV$jc4^vn(GQPe~#l&TGM7CG-Lq|mMKK;|C$;($H z%+tIVg)x@d4{1arO%ykqk6GHNWgnJ%iEQa`|*SO?>X}STlUVw+fiY)`Q z^ee>NlG2-B{7NkP(T8l&M5E!wm(%1Whdd25G&E9;#>)!}@YB0nD;+f-zrKz1aCO*4 zra^(RkWOv8Z5I!BCCS^Ii_u9JBZ`PhcbotUfJ&~kqq|EWb}FU|-?I2=^CKxXHYV)2 zp0eFUTWBY-y9k$`lvEf!*0;|swRcR*n=UnPV<6BFSGOI}@di(1A$Ax>0arMxp}#ewLOh)t8J3gJW_wu zcCK;qkQH|-)|2|Gp>I|%arw{^NI9jo{<>T7U5+YuL&-D3P4h7`Z+$v%7`A+3G*bbS zIn&x|8QOKRx2Lu9+nP)^MWo-qPm=?_CW6&gbiQIR=|g(a$1^ixoLhuG)yEjF`I?#n zWCcqD9as)h5AsJz8jXmz6Jmu&g|FWf+!}VO?_ZGm|AtIoWR#cta@sVvHbpK!889(0 zdQo!C7OYy^SvL&{9SL2e&>)dc!NDkHD*3VA2LCCuL8smg^XcIpY1w7dOn)h&RCudF zPIsE<>~FW&!tCP|>%mR)?(E`5AcjPNuSbwso6}zJ1A|xC_M?oc(|cazd-Bfk4X1Ol z3<-<((>$!u+Gz(K>(A@@YnjIR+YGO;nX&=ZP{Bj@t8#JqHDa-Mv`!yH&=RIGK8@8> zl5ZJi@=H)7x8;)5jp>?vqc%RZ531KQJ8n?wy7*@LYr?5(q4#~*64`@EdC zSLA5-EQ#WpD8xeYR*61lZDkuvRiTiDv4AM5Q23v=0iJ9(g~711)@|299|M#qIjW}9 z-4mHL-_(j0*cPVEt+LZ8NhWV+leS4&v4(m>+a1y z>#x5L)^~=V8UB?!2&*2$mAyv6B;mz`G3SIj{0+uuNh99Z;mngx9n65?Vq3^sBeW*T zqj02Z-ntDR{G4Kwqlry~O`_>X^G4ALGL1E7)&#d@hR4y2e<+|)(o)g$@V0O>ze_`H zV$h^0V}g~X-1Y(x$@zs1s7sZfkQ>M&9gQR3B`mz-EYp2SHew6Mr&uAXhp-xJ8AiD{ z5rd*$&SU-*ty~-Jk<=dFn5;um0lF=m)>TyW`*cr0sZR$!<&``^yDx(r3oP8v-bR4P zm|9SCP38X;fB5I$^x8Y?rX13@5J!0Wq(N3$(vdj3L+dG{S5umeh8dhCjt(ngRw2@R zF5TUdISwWDY>`=5+!+rC@GxF{ur(d(RV&RD-J;ctM6Msd4o4F(KFjD8I-%Gtf7r32R>Wns}TZG zDg_kOVGVA~)@CEu(JtBFU!0(0fvIR+*|a?;+)PBO>Ki>Zx;5gAE8aHG1%3? za&8WSq24(=f~9M|nYbGx4ZM)W-Q{;?AqBNRgHpH`Jh4TX&C~UOJ^|0U$sPhR7I*#= zx-76{5tBK`!OoHvi-yr$=JTIF`TmV{#0l`pu3 zlmfpXKw!WC3~OrAYKE;Ynpv8xr_b}g;;xygq#w^01HKLNg#ZDT6TN|@^KcbjM17V= zOg0oP3kVOZDgtuEl-dcVfSx}m__a@IF1q1DRY}v6MK>v~ZBem@82L;A6%D;Oy-muo zj(o!^pu={wN|>MhOnGmmY<9r@7;wFr>wN(SM}h( zdJz~r2>@rvO!Fkdh7G429T~)4gdGWab`5o5vjqcC5g4X&le}$uzEwbkRSYCK0>sH% zw~*%@D+L=)#t^^%G$#b{NQc!p#Dm9h;9WKnQMY zC^Y=56}B=0UwLP|j#=>85VtNj-fxizT?d%hH44tEp(|Q9z4ILE>PbpUGNK6Q;&qVZ z%E(l$D_OCHxH$(yx!(PHG|=%gSD_j6y6|-OBbve{p<(Wwjr`AFtwBE|KkE*LHxx|yiIf=HB_{9$jbR=grhum%V;-(qR|elm zh_q$j27XIvJV)K(NCidcm6Jb9q;c15LWviY1mi{Nj`Af&R>NC$GO#CSN@J4Ao1BRaOKkiBafe- z5@IiX6k+;VLR1P`6%sO4Or54gL+b?3-q)P`TBb``(Ns-OUP_&ZnQ}e!p?cu@rnHVs z65hhOeoCmDxk`sTwK4VN7Urd~*hg7;V@cRdC$He5FUdO1)|A3a2#l4_^(z?WprtYN zTicWjuSI0%R{TK=Z9JX7(OQQQzth+g;>%$Ze)JX#&k)t~==?<=Zs1#D0BjssM;M z#E_%@PHs-KiF`V=8wYU~oQz?RJ?&`E>AsSn*Z;b^Mq%C-j9XvQo{AdTK?ql!7ev^J z8JE+?(Ki&TlnQ3j7h7KsXTpX>)8s`r-LfYOQ#ETtu4rCXac{JIe@05g5gt$2ikbi) z>OI=N`oQq+#y0he+_}39SgqhicgAjz{-K*CyA+!(#P@VuCyTSOdHUYCc+4gtkT8a2 zvsyd)XQF&}KzOp`Kt^pU=k3D?G6Yaw*&2X?lg8TNx>J>0TWy~-8d6{+JqC$Z>=`~s zX3l&o0>NcBU+n0g)ubx>8SVRWANqdfk@S>0VmJ4PHA7e@>7>>MV-60-nTd@}<)~wS z5~C|ExtSK<6P?q3xb<5>Wg8?c&x7OMPFKn`#5NQgt92!iQYaos?{|ryt_Mm2jT%yo z^}soT4<|UvUfT!X^Sb1yLCGuO{jlsScNS;0d1AW$R>!Vw=2MeFAq1@4u8++v8p8by zDP@Xm&fenmiA;=0%|Ymdh%E`o+&+eFAvm-xo zYN!Dvxv*Z+2n~>d+1S{o1Slfw+l@W^h57&l^?F{7$|u7%%z09h6a#N-R$npFgZD2a ztVli2XuKBJFWQN8W(Bwv^iNs7dJ?! z^>gb2rUZ5XzHtu*0>eRX$plCHUJ|TLR*^0cW zZIBBPWS)c*tr@oXYgCveR@C!R3;g8@YP|$R!u7lFu(k@b8it1I1P4UtMn7FK1aQjj;C_ApPv0Y;!LmLuHq$w#h zu(kiVXZ+K5Y@v-2j%&b4%uH-HQKswJyAMKGKMY8-lrVAxN-I>$41qC%2|$8PII&z? z?QMYhc05gvy*pdvII7Nz@ujZ*l&2@h|C;XExh~cpi+uKC z(T+o|O;#j<|1lMKfZxCDsJ-YWaz$^-VRhX4lqb%@t`%!JpVnF>8kHj7dK}Le9c`He zYbTH7`Gck*0uck8N{kfVr!GIeBOUK=f%6`+7u?C7pZ&&Xb5w^YtSi9Srnnlx%42}o z4$w2%|?9W`HZ>4-amnB{wj-aeGkH$9#LR}m- z2uRkKX?L$g?HeJiYuzk@(Kh0t5?ERjZJhpA8@|J(KQpP9viwC}XV#9y2}PfV(9i}B z%N`p;NKFk9$QQK@?NS7UJS#HONiwH}b%y2+%3FIXa_1D+k*6G`qu?RzO3tT;ZB7s{ zfB|=S?c19s`X%n7X|`#mZyfAs3Dj;)8?k`{?UIq)h3yoJ+D?I{eU^Mr%wk!XKWpS< ze^k$lq-jd5{oCdJkHt;&5%8M8P@5#qVqgZ)YPATbW zKPB5MAKM#$^3;YV*jU z*ta3-0K&FRSe&Ae z>`pgt2@#9KC(B>oND=J9ZP5hUaH~Fj@8BOi6%mLky>T?9T9_Xz&s2HWT$3dqZ11Ga zR_))d&P*s4oxWdE=6H0VB4;tejig;Myg}ft9F7qWeAbxko#i3IOf%KAzMH*KP0wr!c5=@f+zjbli&%6@slwu#)<#1^Em zY(-g$cs6U=8x!>~8R4~#o>WZ1V{||y^9kgtc)gq^O8&!?V+dhyTQkY22C!=HnqZ(7H0^he5WrFPhq$&rq0$hr~kXd4N!4YCp7BzU&>%ns&hLafqM z>49_fywzWsS%a>LMMRj+B_1@fQ}_@dL^F#xsQ3t$mCf$$plX<^EK;h}X-g8fz%`z$ zS?Jneh1%wY9sR2w7^YAl@D7!(WpUOqvk6Vwwz0nVYpof59lhQp@s^hoJV03=qtM%k z;EqTaapcLm<)KQZ6r7t;z*nTr;>)_+(b1^)!Y->BG`$yVXrJZvux*oB$D@hrDYB|< zfBF*sD*tF3%_nIZ=JctJxBNy$X}aolsp$%p^_lzb@zl>`l}%IeP*2)Ke|54Qca8cv z`qu9hQER7kS5?K{CX~h&O0g>==_6Hn5d_`hPD|H4!CeD5B8Pfw{$Bl}j)euF4r)<> zhW>K-I=q`Bes#*8SiV`wnORM_Bwf7L#dGVadr*aKHCSDH65>!X%`60{H7<|Hefzpr z+!4QvP@N7;wNaF+j9P;}BL_8O(YQWNSwd~_AJ6g>@Vw3ny6Sg#*Y1F#G8!IrJ8-!G zh(ev*|8~-hM)mGq%>6)Enr(yBWK{;h-Izo+Z|2?*sEWT_zhiCeAISCaW-0TIy6cbk z3m54c>yX%o<`to?bg$Yd(o6iOuM_pnr(Wk9lZ{>tpkNiL^H?DFy_>nffM;Ixk?;oe zyh_IMY5b?WpvM8pu4SsohO&(2mj;H_KT*ZMp?^k_RV8+UEgwEZXKN`B*U?%(b4SNx zqmg(s6!PHXFjN0U(Vm^dE&B$vdG)!ZpIU7rg)!e zLHJdiuXE#7OGET|hvy*K&)0&F)zCzCI61qd&X`dy?W-wNEQ0`=d%fQ4^#^n0*qxZt z#Io?Ev925bYsJ>jPx9S{>L1pzW%dGbf2MY&_ZK#|PWgck9XMQlRr> zd)w$)Tx$($LJK`ATIO-xnjYd*S_NESL3o1lW<=3kk};o{); z9+R7IHGt|=H=|s|Lp)t#hg|Q==zC{H^`lL^2^p!E1EPqj#?n_i^YfZU z%sxehWy_%D7gL+*hIE2B4)yyw)@Mi7nyK+6Qc@#lak+y6dOh$r@WYtYFN~+KDi3f! zb0$+Js``$V|7ruTdq8*)pklh;(RG1rrH}e2nDnofpa1zcGpQ)9!kJW+$@Ns77K2Ad zG#dE2`QmBJQtXV6Z)La?2RH+Qa5)n?Z$gXamQCjei|uBiy8K_Z!hSA{m=jWTpgEXkkWtJ3O0woPMF}9PU z1BnJyl{ehU0x_c+`ABUIzOQNcIP<%zi3m)9GxU(%C!_ggSopB<*Lhi?ou3211#rzR zYCTT@+p1U7?uUUr2uu_1K$1N#Xbt67M_rb*LndX+Uc$x`d9dVC9YCnu7bT*iwxbr^ z2ZSXT1LI{Gsr@>1>e_-b`%l!yg$E(pYF8vPrnxJcMuchWzS%@KzI_^dPzB9wnbe_J zYhm9|tH+EhhgOYA_ajO~A(s#nmiE~;V~C6|JHEq38gc}a@w^(Jq>m)PVrXMBwfNE* z*|E`**JMfsxk^~2WXv{hd4|{YB2_b{kHp)79W$}*5$S5y%}~VyzCdcU`+gwNO`XOm zR&@FE>6EQQ$4M+)PvX^&IF5YN4_J75W#Y^-sq=op9)Z$zr3wik&CB^`evp7y-GSy{w|x(1f{gz@iij9vR)$VxuH7JHk^TQ zd$f)?$wV-{GFeh&d0~;cg9=Ke93Y~_->7uc?x!X!F0@6&MKGThLCA9*A)@lN9Pmd( z!wgB$^sm~o)R}45!;5l~mlAgB^`4d5nS(|c?gGw?*;KQ7M?DRT8nj(Kk%t9Z1s_$2 zo2j-dIq+1~KTN*?apU5p^Z^DxAldH%am`>jdiB)ibPuNwTHtTeV8{wW756_|Z>~L{Fn199Kh!`*PW`XL zKi2995-%)9x$u(>#iI(nTbO3<17cGx7*jhH>Q9#J^p?q{jyyghGnl-^o+Mr}|1H6*egI39amsvPtpJVhlLX@&i|cKp51U4%xhsaY&+)x>P);FCrJlJtzM? z)J(-p=$CZ&g}4X&9*S6rK;bbwxZSLv2F+_ek!FmCdXRM(`G7i?X^uU{^uNtACebtIvf=mG;S=)R|E=lMGJq=@_IX6?Hkx6 zXa2y~dN=Gt3_<10U*&=xeEy&%VHaOMcq!yfn0Rco1CXk^a01b*b=04|*+U2XQ1RIm zIXo(+5}c+4$B>M^GKUZuzr8G2U*c0t2z<4Nvdr8@(R=!u% zLH`sYnA9Z^gQrXM&PSEZP~*<)%5P=9Xwl^GVWJt|V(iY)dvLN@>al7$Z-k%H$FjZ2 zJ#|~y&szQ`(~fTk?RfEK_Xn9#LI^@sl9#h2e_idJ)yP2M#)zy^>dzIB6%btgQF;(j zbFQp{aXjZ<1QJ55-pDz5m8iG?%Y~uO#4URnmpJ0qy0vu99*ZUnDwCHZ_K4(t2*^II zalZw%KZo#Iu9N^L8#1S!CH~4pag?@J!_!I&g_){LsR+UAY=>rQ<4wreJj5%3N->R8 z30kC|%7}QXV8}RcbOGS}aYPV$)V{7TbMITWb7p8#E8{>|_QE)rG=xcnEfGxTqZhb3 zf9acz13U+n^=ewO8c!UU3(*x+nd?!JD(J6Fonq(LwEma)MNk!~eQW49QtWt?c9?Cq zdI7wb#qO)GhBbJ!tP}`L{LKh{^8IH%u4v;c=aDhCLez@B>(-H1jgtEl8ShW^WiP;E zGi<0W2a6S7B>W!JX2pSHpCGD;o{10so`#FwhgrXTgZ`Mh~_u{EiGqt z0C~=Z7%pen>C(*LRb^c9B8Y;THOg&^CgaZQsnE9^(zp?Eg)DUmm&lCn*Gs1k16=`NDLrm3#wyWu?W%w){I_LWisv&OB4vs%yGk3B4E;DdV; zsOs{!4;@(o1mrRY_PFFUQkyJ;jMGayK(#^geLg9?1n(BrruKc>%(2vkB z#0gb$Lu2P}(0|>)eM{$~DZHs!+dYJHGaaVK zRt$fs-+?fbPz=f@cMZBF1rY&`cJhCC?YX4u#<=C&^S0D=FfKO~_RZ2LGAgcp3r2}! zq;MxrZ0?f|DUjW#fjf^{IM{uPS{F__ZzJ51(3))|+DT{lu^(Qc(b5jUs_#s`e=}uL z$XaZnl!-NMtsLYl7D#Uh?MkJy~@e* z%KPzE@WpQ!DzBF34eVU}0R8&PW6TdJQ0Tu#K+&K5wBe>9N;hMuw(-o^%91aIDDjoE zIz|afm}y&<+IBPq;H0$)KF&}F#XT`C&@=^p@2+{oJ<=@26@>QKS5WLO{lGGiht0oY zK_|0}U%mRegxBOs%p693bv~BxIm?Y?qx09(xLut?M{((EcBqea8d>C<0Bum3DXkK7HlG^t8~X`N zPiaL8X5R^9eb~bcemyu5rZCy!^HKoZ6eFgjQZstvpF7dP0G#Z$;Y#Q(F6fY}@XZ|U z>f^XJce`Y5`-2Lj6Xz`1b1_8$9H}*~L`!t8!_62gt$7#z+O+|jmMJa zTJ_%2HnbD}4YTt%_9Ue0o+W_aA>XAl z`dO^vS?WEAx5s5bk{qP`RNAIb=BoxA zob*w~rSe32(dQ5yrC*eBRF#`UTT;!%B09z#xR#9)Z*5I2K`Hk5tAxL2seE(nmIYA6 zEsUE}HB9vs&_`m}$apfs^CT+oyFyZkjNRc*0Us(FPV+l@teW~ZYHrVe1Ow=UK-04i zZ76}U33=z8g#M}60yz8aDM~`XN@AyB7|bkZ;Mq#>gI}J|WkFziLVNh=41wg?P@CMk z5UxXPnZO13MIfd&pvY0&-X2HFZVa`Xt_`yP2nl zXZMqC=X_d*B6kBZdIJG?u#0c?owSCFb0%;1&gK?nMU&(49d)B!i`i(;#Po_MWU-1b z7fth}-hWzJsDg0PL!e;+}%r}Aq%VU;HR9)=J^L!b7y`_LzT-~7g9-eIG~%PWb; z%t?NdLm%I|e=d&VFkD`*je(_LxzN7J`Xa@vQejW#mT)c%5+4h3J*EHkPX6aR8@&fy zZgS&gRj%r=F6R4EfF;`TynZX;XTku(N2K2eIyTk1x*Kg5?1&1dXG*|=1nwoOq6R3x z6%Ga$Zrry^Mw?xeBsor7$!Gfe`+nYk6Tord`@4WwWm9n|Mj5}JJqP$ zw7){BO3Bl-F@>pW%MLudiF)1t_ zduSp71s+^9c!HqjZ(FL3h{258;x6BDr|6x6E_sResefb~$jTdwBHU#ep$Ups-1W~w zT${;uFEqV;FHwTuKWKuSoQB2sLbtR+;gv~!%be3~>Xs;KZv}~*gO9u*eHP!J`SodL z&Z^C&U((WO9uzC<9z(fc?U@bkD|v>o-&ax*ucOjpYje~H!@bH>3x&BZ`NuU{pU z^C2VE-u>udkE*KtOUJq}ip5dCPcIHzO%zjTzauyhatQ+GBdGk#*li&bF( zzbX@Y(cd*S86CZncbUTy#$d)p&4UFvY(Gf;K|AU3K{5pY1{9U9Nf9r?*+T4lZ{m#$ zh9xqSq{l1Qw!|ww$QY3jx+TucF25K$)#|2wtUIxdNx$(+dA}rIRWdNL+UqvJOMIob zQLh%9#Y?#KZd?6is%`wo1Ir3(Jm1>!{c_=Nc9g+oB;qN z#@`0h{l&fd(`>C1$I`V7I;kGmQ`PmHYHtDy^YLNQe45MxxTNNgc*6Z)jo_-ZTWZ&$ zLM6whPR0Z1gOICML)c%x@B4pBf%>14`f?$5SLuXt9%ZI{hQ98L3-T&H=tpX3h*{S3 zxW0@Z0V_@gwt|fZLWQBzlQfx~OI)vl<4{rFR6Dj9t$9r);tK1$B)cv~U~2*%RECu0 zC(VYL=+K;Gm$TBissMEpiM^`N4V`r0PebiZ>V&N6JoHq3<}QLyBO4bJ+ZCvCoy>eV zGatx8*C5v02FCh}%qmwB${@x2YI)5k-6CvRK<_(;+S-42)_j$UOXOxkcTMRZP`+&87r5pY*d0+s4IZfk5&? z2i(O9nA!l9g}J=6(>G#yk$vM2ubMQC#6U=teC9YjjH@1OZ(m72Q#3>Wc1p1mToRXq zJzKTIv)92id3*M00AleqG@UE$FP|uLm_S5yMespdpnh=N71-d zlBasy{YS3bW=6)XCFYlpJ2_@?X&FU6XlexJhTu;FSU_op6Zy68&nh!Z*1{w+h zrV18rrSmf0JmRh1j%1d8-|=6Hh=}86;SC$6Sw}8!QCS8zzOQMrpz%O?Jx~$uS&?P% znv7 z&pN61x9-1FVTyN?GTcwi-F{i$hy)E(3ADLIP(NlmY7}KCA#)ryob-74JET{qwk4e} zjVWY}F6p}~`bK(D#euSy9`A&~EHyI5HuhSy{qsxO4%zxt_FT&WPueUR+6{=3TLmyh zkJxa@PS9E1C5~0Z<^z!5Sun)a`=WsVkW}wk{yueV>6(M9FT|Bw(pG@x%ZrW__N%VQ zRUVn1Ea7cf+&<#2w`M`psQs$O3$&5RpneC4!l|%Hcm5!4p5Z*dhc>k1V%SJsnOW91 zxjTCWO~`k!fu>pF`r~MM=OZ345DzNudVCua0MtbFCv#()G!T`xZ zf&~nhYdXKME2Bu$S;U1`JwA%qF}+zPCrs<84vs8YT5& ztIomMsnqW6V4D#LB(W29%q^%)Z-kxxOn8&0M0jOS&a_F3<{7;)J5`capvVl)KeznA zqU|X}>->7*jeCga@|>D&spZQxJK`O=fSEG#a{i-x_rfi4DhCt{1mh z&s6D!r4kj}x-L_4r?0D|87VlCtksO^*$1CRJNrb^M{Xz|4eH5R*ooF(1rRjDm=s6) zbXhk)1kX3I9$1JB`0o*6@1O4@gfe_-T}*rKc$i`oO{6W&aM-Y@)U~Il8X=yn2)4x? z_DU(8Q-?!ntosQ0D2-Qbq9(!OC}r)BAERYWjE~4!9czYtOF;#pL{bfF7fO&7ypkxXrL@+VH+dAd`1%V?bv&p z_UiURnR4%~Jt4xbGW;;tdhx{%&iMRVYAeW^JwXitBIM=B02 zF%u5=_45S&%`Zuz-91%o63r;{)DhACr6_`vMrEdWronLIk-|f=z2D~yZ1*XQ^JI~M z{=0S&k&A8X|1^c}|6de2Y5J*;@0k#^vo5mROVFc3hd~1?3G8uK^&HHJHC2GWS5J#$ zse3}fwMGP;IVL;X6lx?`D5QJGe&WAoI{(ai&@}Zs7-3cJ-`0(#!Psi$ie<6bSCci#r5&f;$xJ zx88mCzT=#G&)(vVr5~&ugP2w(#HA`~b61*_y+07kY#C68 zHUE$<0wqKy%zBOaQty*Zacv!tZe#Ztb44h{bU)p>ak_?G_Q9qWmY4|IW3w6-1SN#8 z;4RKwUZs0vNcs@Y{ld1S`Ga^>uYHCPj#Ve}c-?IZpiGr2U|P*EI&K|zMs+&5OM6Uz zm+IxB3uiyiuV5wi-lp^?qVx|xeo1nj*a1?73aGwz3R!@|4xO;Mv$IX~8y%<5>R57) zd&ub8hniVYx=>jeXJ^uk^cjtM-A_?@Zs#9(RX2@&d@R;>5cPLzk}-wcAz0jHFL`dNq%&Gcu*3C0zUd+D5*ZaA_%~Uze^9Quc zZ}N0kNKk*OycB}jT9fyRH}BnF7MMzm1)fO9(X-x_r*6uv{xuL<3)1fXb+Mk~;jhzf zqlUoZ382GMi=!fGfY7IZo!Ltm&sw83>n0;_BuvN$lu-jk%Vj+fuG~aZECG$vU{iUG z83ARzS+YViS*J|unVSBZy+!OU!6dM+{UgJ&OZ*=4s4&o{-xyCmw}na=G5pUV3YxCo z5w|c=`3a7s)8jIw@_q2r(K03W!T|YGb@wz`E%LH54^?UXw8}mlmu6AFX9Lrnb(6u|ims(0 z$7Y{M)_K&rT&c^L0k|v3TIr4#Ya(_@4AS~7+bo~-J`t10?PqS|?u}R?o8hj}J%YO` zDZno{Mg6K5Jn{8e#bmIgJwbtlM2szXCVLx1GM~fOU5O|SWlzxGA73OkJLxNq&@Og9 za_eK{B36)i(;)@M?%Ww8(37PZupjXM{Iw>=Sc{r zP*LK+rpxL_jM5sB_RL;4eelKZV*G%p3o;yg;mog~B*WTgMC*NE>oN?n_c8LkPtMgx zB^?`HhicVDn+H_A2v)$%Pr!bT%~%dzv5dK<|LWIqN7(bXaIG};gsyT8%Bk^goZoLh z%)Y`ju^|3bgiO5WSw@a-TzV$q=bB1DqT?GVbx=_WAgIn;_Yv-ilk0YepAY#me`n)q z0?|YN<~TwqzxG}|3#Vq#vANX36?367yWe`O!+s*`XCu3jfojWmvSwX#pc0u3D-t~_ zKwe$d_T#q1YiAuCjE|8)hLOwo;^Y#)n|-m+UO8+qMOSY4{h;8Is0;!_T!

      +SR#o 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

      X*_) zUFS3JMkhS%S$BS4LJLYVJca;?)9AEA{rudK^|I`;0b=LH-J142bKFWXsJ8i|6vD(0I> z&7hZfdwx}K!nPJj47A+TY$9nox{-rXC9xw2D72uu4%#*YbqIx1Y?&6QPf6qlCzi61-s6lf0=3;K&7> zeg2xLRt3~Mr@|RBI+a-~35N0>&Um}GGaT4r$Fh8xc`^L)R~ToM+@ zkQB>{Jd_4&n;7!OzLDth?ACBk7V(F>lDWj2Sm!sV#=NwhRw7?pp`c+vGl2ut@z`u3j*UFzd&V2n##Yn$Ge+tsLS#NZ7Ci& z7tD}N!iY2qSMMloVIE&cs&0;^`7Ny-o^+yiZE-20J9hhW0!v!5Med;A;VZRM_8(G^ zL_PsCnFxEA|K~=3t*^f*wc-~Swt6nA+Qnz)A+7A3GmqokZbl|kvR!->qo}*cEv~l? zZF18Iq{cbWo7|w(qN&=RG)G4n$+fITk#}95bd;e^7MZM^NEEAXR=)+J9r6vc!KB`f zpTp^IS$+-+b0{YAJQv^ixN*UBlaQ)m*nc&1()RlcjI7lJ*o~c;U@Q30q-qxzCpZ@D z32KkRZ(~yXe@0abeInkMm$|B*u4}e0@U!*k{h4H9*HX2_HIii}l+3pJ?08mq$hA;r z!r(0xwLUxKJ27@_SKJSLw0P(1ZGq$>54=vV@(i<2exI1TYrb04>2Vb>qxHxg{ALV@ zOz?lr4i*Dkc_uR#yRy2S#}^fMj8abuM{_1ECZ{h44m1YbYYt7#pX>PeKl&x(KwTib zHPQ8w4%J`Yt7LUFrJBYWKvSBdABuuW=p&&&ffs!3et{l zT0LOzn#QvzMcx-Inv-ChQNC_}LZ}%un%Xn*KD#-j)8D;SxljV{Jq=P{!V~*fqB9q!$MjH`;*8L}QE&eLn$riQ-*Wt@YoF>#1*SgGAQj*y+UL|3wuI!loEuPH-TCAnNa*XsYwC^|{-m;681Hv*uUDzPw@(3!{qXZf?EV9ANZWFCxVW#01Aa7dIDY&K&1PtL;I3#*u%+ z#z{Nv%X#}f`%{9e2O!{_FX<$y&-X>p?G!t*x6jd%ILg&dhBvoC(O+g9T8T#EC)5#2B(=x{^2T7xSjNg- z>5!iZ55uC53-f$Lk26Dym@l((-7A>gGAAyQQBYXGb>W~#G zE6-lre|t$`$)0e!E*|geIK~u}8z;l~h*H=5i8odIm=E4+7LiHIWpZ9O=ENiMpZlB6 zGj?lk4-`3e*&|q?VSqSjA>wrM~>V~N)R#ndM&@7@_9u=M|mQh z2HsB6aQzf^#N;u&MbEP^w{g~fqmz4$eC0|X+W51BCW5K<{TgqZ)cXU*nOb(sJ;kb) z)~c5JP~YwZzWLTIYCM8Me+Q3?Awk*~KMAz=G^6p2jlRqCr_CN|-R5GfxbDA9ZXs&| zbjwnE&M_w{#TMSj!TELZLgbfm9k$_~p41=)`Xy{}Z+gXKxt@#@F?B?Pg`VB{fMt+W z592~P`3!dIR2A@j;c{SgYdj$r$UfSg*kM|v>MHG4e1jI=P;ssE?&KYh?B5d?C)&(( zFtWAYf??&xiiSwB@WdHVumwGs=NEEcOx#5aqQ(J)Z%tw!(|D2pqK5ZXA1@P^u2mtm zzX0}^4N1br%4AJ5futsTJBGZM8o3t7+VI%esf*`@b*wJk=xFXs|j~X21ogAo+>)ALPmInQCU+OG;acznNPt z+eZw2K_$q-03Q*!-kkofHm_l~dHzQdBc+D7J)dE764>fqT5vIi%28X!371*%2w~^V z-j+1Ve?W7pUL53{fN}87c(MI;P4Z9ML*JQo<(0DZ5Yub{H26OCG|3%TQztRzh@z>5fNQZgqY zEJ=H~6w7+3EUhzU_hyg6SwzLp>+ixh5Y>`1wSPsHh?=!AisaZ3$>e{p6rg`XZ9p9~+w`(Q8amwTm2mUwnY{!XPopZKz<&u7$Dx;AME=i!=j6-1# z&B}Dx!^8uU{$%?;;qvq6tE_E1KtAaPyK|O)bU@mndP21?FIi}{8qriiXwau_q-;kF zemrZX&{!3;%$S1;G8$?=F*1;KL=O$oB#ad0jf=HLIe3YY{15RT03WS2S%c@x`o3|J zYZl&ufN^~JnS5BcaGA4-z`_^xqks)T(p&M8)&@KDQL(5cHgMzxn<2OBtpsd@Au*E@7F83U(H z&K2?@Fy`O1Ofh1)cJ(5pWWj4hPj}saaOD6S_WeD|50#A%wgdxOOP_GXFfsSVl!%A1w!A?(yzpE&b+2VCM*C@EG}f({gK z3`J*mt;>ecb(P)aLw=i`rYC_vEhan*SFjkya*#K~zbNZ(HmaZsYB{ND^a6sB;ZOkzvKu=N|ReWs-DNB0r?i0Ys`pAkGn;V(Fo;kU5=WXS@ z=1ogA-gEk{F-bRgKklzJ76Im;R>=%eh5iylAXkL8WPX`pM~O^6s#eX&xc{lj8f1{C zmqNJzW0@1U9nG6g-YaTtRz4)8fRjl`nNOcNdbQOk!>`jmwCUEU;`{+w z>VMt+XVoD75yd(+=t!du6K8Zt*e2rasRf<4X|6ui%{=exwkad1wI^o-?*4LedRNJJ& zx7IQ9>=-e1s8iC9v#l!1G5I=MU-?=bl^r4GT!!>JvDSvc82;>!v=V#qap(i`f&2t{ zSOY-pVR-<_dP-Nxt`iJ`$DVQro+lY(Ylg$8F>tJahL77=}QF-=M!eV4&J8v=4eqHa$DB0<89d}MFg!~VjAPT zP}1Fu7I8HUJJl7kT=Bk8?3dLl3S2(&@ ztCVXrB?-$Cy@ugrVo3JH6Y_9ZWp1OIahDh(K&)k`YBz)7Tk{cF(xJM9L6_U2 zcRUidF=GjADJPgG1eCDUoNZ2VABAER>ljl!d8uDov6n4D7!uCT4|VJ9ips%AK2Wme z8u(~CYhcHhzAd>Ng|-Fx*H?rVxNW+|pd`T$ZUeFaIKrpge>*MZ{#Fb>1Fb5)!h8wD z5rn@)kG@WqT8lYjGMbJvHt2WZi8UqR+K*mq+{ug9RaeL`7W&Zl%LzvU=Q1x7ryRBs z=n=1Lt{y{Ot`)G0bI2Y6Bw?E5XIpdDWIfSG<)x!WZSXlSvznU}SRvcuSNxn@A-B=T zucBez-B;QkxA={J5m%ikAJT2%bUKkkOmp7?o%VIl(IZo}tBsTH+WL$n-2pynaD|_M zx~uN0^+lS(iPfdnk7+y2`9B~lc}W9@0XwrS6$tb7dzi)pxw&P zB@rcie}oweUtE>4y&O0G-UFK-?!q}--&=j#FwLG0oOrcVL@Df`zyymIc=sAyV096jLLz#JUWVag%RiR#waNj#5iJy|CZvNAOJ+OdewP!5roJg2?V#?4 zKeoEJjtFZftw8@5s4;^we>$yzE7`5&FshCc`MF^mu36)Sm3k@K!mSphGY)s9Hd>OM zRARHE5M~s=ooWn6BB{l6VX$@Gm0%3V@8??RAfli7ImjE53fSMX{(mhW{2tyj$yr04 zMFQc(8z9TDs~T`n2ab>Jn$l?fG}SJ>zh0up01>|h9!I*sck>g^8JJZO*aB+5-3+x2 zi+&?5V%E<(s!f`Iu^oDc24JuIdnpC=ROd;hPNxCS7tEyRZ?LwH+*kz`cTI@S=kIM` z+IaT{%9-o-$Yj-~*ZDo7_8>3E4*DzsGo@q6(7c`0kf>)wTp7N6N*pA$(uW|J`s+8; zaw4ot!FjOFo6`HsS1q6Ywtv$Q#;mq@E1!_1c;{cUt;>IMYO`w)T{Fa86&H44%{p>i za6v`6Oi8U``;kLtZMg&pM0n!2%<4=7P~7xU_7J*9)#KbN4G(iO+>EtbOVg*<%{(+8 zNk3q}jpfU%$tm+tRi3`c;L~j4^StpUi&FE~6TwH1bV7g07&k;E#+6lg9%j_DLnU-c z6qG$NdzdPW_x^rK4x>Rzo2B{Z$j@omvDbVTTw>;OD6v!(;#AH18_h5_Jo})R<|HBB z**G6&QKYn{ti5{(j_=NnUYh0>V)J0$n2$$e4&3nnY@%pxO!6b5BlPEhK!4?He!5Q< zXM*uyksiL0e8L04y7A?&@l&jIChcpkBSZ$)myPt{2Zap}i>WvB2SPBur@Vb{EZ8%0 z92`J^jY-GH%%Z>}#-OoQmB8dW9B?2;3s|=D49hNo^g=mxqDJ82(Nk>w&^K zy9eVppXra~X~~*qR~Z@_>#t>?wDSta^Sa@S+F*>x@H!AChvX$TKd_a$rYnVgoq&2d}lg)sF3^-xme&_hY25JVM7FStGE$ zCKGvaO!p-|kVa27*6V&Od@yS@GfZNC+_zLSy2sN8g{VL5LnNNX>+vl3dtH*wv6Z~k z0==XF5rPW6>$rgJw%=fy9#f-V`ybGA>;K6H)_ziRUz@RVpa^Z^@x+tgq;{Hr7u@#- zcb|9BTl-#nlK)m&M>X^34QcAM%PS_>SmsUGaJ_Z->@)g$yzA(dnT&DRn zz5#>KTkEUEiToGWA*uDB4;13CLDv`c|N1!@SJj{OpibC%*B^C*lcw5`&1Xi5;-{9A#dw!CXUnVsI$*-K)4?t}>SUMi1bNQl`hYTp+l6LPe!{JGT_)Ce{Y5n&~CQ(q5pX8=k9)g5!CA;$Hx4O>gVBI zOOtc#<8>zVNc>A$sG0Hc+TM@(uEyHZ0vz0q3A^UN_VtjJKrG?&{7cvlJ@kmzho=}C z>yhx`c&W*qFqad7>q>C`;cG-LiC|+i8ir%^)Wk0ND5TMK=wbjCxWtkqcdkV#koet0 zvGZ+pQ#caZZ&$&08F3p{x1iwghWS49J<)WQ`)Uz)Gn|mKTmiHb<8Y)l-@=i-ltv=yVMwk}Nd;HyPvNZlPMYX4|U zNMnq#wK?R5eZCa0Pc4_6tee+Nm|0h}DlV4jJ>XcGp)TZ=Ez(__)sLu0>cP&f^V3ZG zJRyg9zImIiA8|B#--fI=O}T7LA?C`=Gd)cIg2iQjEYoS+2=bT5rdc_b)oB}rRlxSw z!@;(BRUfCT^$!RLu@*q>#h4xpfl`V}s(VLREMcYn#SwjWuq5Q=FK3JsrcBcy|6f`^ zcpv`|4_I)6>*wS{UZd3BGsf!`)PEZiKYL=V!+@U-sAlm&AoP5b>_`9M;72H?cbwGZ zxF!aNzB_p{zLAL${9O?D^>beN!QN=_4qHp%eCu-`iPnju{P3RZ!As{6{LkhVxv>`C zNO%c(rV*}fm@IWgV7H|gCj{|*Ir>Y(e?S8f0WnQMkyoW7s}awRM@L4&Wo<;(Tiv>?+d&f4Mf%YBnqU0ht?kGPtPEp?O#^ zmiwvP7;}vJfJ?*tD(@5!KtQn6&5bO(eB_d_%ug<&l|lX{`7s<1gUOfk}Aueqeep7JE#m=J8D>q+J{$!zvcRTse^q)NQjfO2jo!s z8Jp^p`w;or7kdaP*CVQxgx^^{eLgwFA2>t8g6AJXHMmkdZZ5DhTz*41rYT8+Zh2{TadXhK=8fYk_kBK-wfd(Nq@E6&!n z!$T8ZNX*-YmQeJVJtboUx3+b^GitA!`Qy6ZbQXEmbT1mN%?Ot7m>dT3IhzJuQVuX2 z8`(+J3gn1_g6?8SCq_K+z3PH}EHGG>=G6i?xDtxq#o9#(ucKX$+-fn=KSuPy$A^{O zyEIV0K0|T2PtePq5hX?Il3&!;7p1#UtQ|>Y4{mT@5_yPq+-uzgVG=U*$4?;=-j53| z8jk>t%~eIcb}JASVc%7JpJ29jOaE-oD^k+8Y!klU;Rg7>(x1Ggp+u+mdE8xB7xOa< zo3n-hYjI^#z`Rx|EZ(V1iG~cn>x+0S5y(oSbP{p!VqRqwe*VR1`na8;zuXRAFY|E5sO%Ddk;e*@>lhQv z*PexjfY8{vcu$Bdisvs>)lveqNi4KKaz#jZ#Kev*vHZ()3{Zz-W%R#f$D#Fj+;3Z1{WVF%ORByFvM zn5e>-(2-jb^H&QF&;B8oWZ>iHtN`qY()3TRLpqL_&X~i0oy$_%Vh#)5piLLHG#wvx zRuITQHxO=v`eNQLa&hHM3>htiN?w_-I2lp)Eq(^1O~2df^O$N*lA{>RCEXGWbi+JM z(FYvbxK$O-&X*0ZzT8RW?hvgV*z~IW0lgpRvNJ;rmb-oL!ZCb0qS4>K)wmp*N#{p+ zt%$?*oY-iAr#@4B`;#5uNzZsUwEA&G$D~ZU`kQe5n8JW){%x zM)&&oU@5m$f7fd`OtK-LIkhZFdnQDL)0~oP*S{z>6B}D9-=?rrf`vMS>?X6$zOXt8 z#znnlppjYn1AiqmS7P^}VP#fe;18(g56E^;8#9(EPS=7oiHF)n{ezxZjFgL<6DAS22+Lv9W6oT|E_=iddCuAA}m*!&v!dI1b*JemW ztOcX?KMgBF`?W{EfKTmWjC|>qI;)fBA*HO1d^O5VI^o%hu-3NMy{$gP|dwW*$T#;VP7!fW;{(k{8p2(R)tqpU%O>u&wl2v z*IV!M4=CV4&bXm)_bO9-40hh~5hVo8?K5_^t=_$#k_6Pj80Y zoZd{?nP|weot9dVdzpWE`36ZIY1ZmI?h)Ei`|x}cet}-Hi*y|%=4ZQc1&aMxnVupt zvo&1qsox#5WcZaRJG(NzCNZ`lkLN#Az(#jOPq(6Y6eVIJl(jZbR$Okv-M*Qup4Ro5 zYE+z?PiVfdL9j7?BapF{acJar_AL-sm$K-{cs~Aj42dMZ28A_(OZ~VUAG5oj@(+OAgT^SH-Vf*!SS#1gkeXO!OJ>;mM zWcj%8!%}21A<%h2vm#_E>v-LMsjcFUhde+fhAz(0Di>+2+Y5CX8!~enG+uiD=uN*k zee-LD-=#%maO}=YW7;ZjZ@EmJ#KGzXLk06BD{(S63Drk6Hfaqn+47e6^x;!~gPqSK zzlXnkWU(We$WS!%caMud%_~`k{AVDWOecUp4xAC;vb{;GM<%C`E@O0?>2rRBhzn7 zb9PvLp<4aE>95QFH`wa{IYk$~zh_;NM3s?Qz@?nNWItEv?fF?R-Nu;-EEnY(V zmytf~70b{*568GH;y6+PTe$aw_bBEs_Ne;nQXqUY1y(p+tBm*8;^zULPV_)wRsD$> zaoFk+!F}2-5c?>FjBS=`h`V~(E5(-XN^9Nr;Z$g+435{;C=~`b-j;8R-sOi?AV@7F zciV{%;)ZNS(PW*ymSdW^SLc^2cT<}`EUdFI%f}_(ANU{KIqIW#=_?tbE(g4#SaPYs z)>^uGzpzxOshy)8(?@G&=|b{J<*sxpC(8HXc7=0}-p`|#UPlfw0_~^RAi}(3vDBU^ z$>-Oqa+7H)ZPTXFC>2Ul+MhJ*_?l0MD#brwtI7(Bkmx2UEE)@;C4Sp@ErBEXZTFvH zxc>^p{ZGHE`C)D|2Cz2<^1QwwC;OXcAWD}W#g$BvqnLaUWb7XvUCZS?H>6u>0c3&+ zF8KX0whE-BSiauG8ZE*1Pe5Ob(?F|wjK3*L@xg>`8gt_Q z$}Q)kP$IEO$EJb@O+Z4ggf+U#f7sbR3LmbTLBN$h)K^xv1#WH4$-IxPJ)r|rFgd0N z^*FIVRliPNC16y`Qf-~OD=nfnkGoIRMt;swkP0S$#VHoCP7@De5>pd}rz73+OMa6(to!&`C054bY-&b-aW4<-{7^k*YuWnC1a;Ke@^-;3k4F3ob>cF>TNgirP zC?pAH9YyPxY*!m!-LO{E(?uKnB!8XAScxyTcHIjHM32C3`6qOn7ArN{0{PqyAp9%I66CbftEi5y`fo<#vavH zTDE?#bMYc)v$|sCb2i=TOn(q=HkY-UrU0j9ucEd3F8F=*)6H%SBL1l8ycdsVY0THr z8K;BbsN8oj^Tpo#%*qt~&koOA*UP=lC`TxU&^AoIr_n@kfL|OUcPZ@D3$Z8Z4FkgOmTkK7}r*0&q=Msn~%H_juVWN+V^Dt`Bnd`-nZJd?Fqz~ zrt;RV!ke~?x;Ai*IVM{zUUgL6y7l?Ek8EMu0m}s!d@|AU!&`MRQU>DdaL~l}`W;C& z50)(y=Y&y|xf>EcR*5R;a4?&wSYY-dcTjZpWuB#``k-`4WV{OK*?{*~u7maZ+EkI8 zICrMF9~Pf>aaO`X@&EBg{TKfjvb(#~Gp$tGupYR?yl|?}p(S6;Qi&j<_HggIBI(H8 zg*fsnHRSR%!(u*A;Kvxc^j$o&!@4K^Ws^nX!<=iQfkKABHx}Q_o5$>r*G@!UJeK!D zadLCk;3<^vZv!>kI!;Q|SlV=5A8K?6YgxaChftS#C#NuEzS1W@-Nac97vux@yfY~f5jn9+5ft4)j^@yj?Gtl@wPHo7!4h5eu$2E_0n>BtBoMyve^L-qPb0>>u6tDw~O_|G5 zzgpjz17hFOfis_s_0NOrZcFtel-amN|I8}?FJGu2Uf=@b{?{Ule^#Oa;}@;pM?Ta1 zIKe=c{asz%YoyW(8q#R_$Fq05QdB#f{86I4ibh<>UpV{H6nFkXpEM?km&LawoQL=f z$Kc{`zb`^`a-v#(!b}VC3yT;Ro)E1XmU+2%r76f|5msa`%om+bKde#84lf@)qksNs zUc!NIa@S}t4xj4q%cm*Nx0foe z)vq+#t`p0YOCeHo?oxB3MAi5CR=?eA2{+fXRBcc`0=b4e1EqMOVXbq;%I@?@;GZHC z*bL6y%(Y?8MA6(AwH{G5-QTo#vNKi_|B9CbcH0oRh_BR}q~__Pn{=x$H5E_i=8Ozb zt;7$b)l^Z#01l4$9wCxaefoNY9u5I|%O1L}gTF5VDurEgATx}+UX|r1k)Vp6$b4Kc zEhN<~>I6?FdTrvpAHGEHqO!Q<#scN*LxYTL!i%x~T;rj&MQ**ggP#Vv0~o*ZHk!VP zsKqp$W)@1k;>_KAc=IrGG1+-+7W2d-P3y#kY;Amejj38eFL~HaCdpF^j9dr?#XE@M z>$n>(=wlvctc$q91c6WSbJof0+PGPIp3nQ0E5z}_4C~X4ioQ==tuhT3jIPnOr}El> zR;h6Tyxu0!{CLk8!u9xS)+J=F;{q>FG%wVo%j>=5^W(^;*PnIOz18bd&3^>^5IqI; zQZO>oJxpO9RCLMK*9Z0hwNw*&O?8P9le}d+WzJEhrz8#S7wxRY@MVG>$m$589*TH) zBEp5?S10vsJh)ewk~Mm=btJW>t%4KV&l|{;FAwEe2`fBt%VmwMfJfqP;wej#iJVUQ z!Tm}l<;%%RP(tx{65;DgGyGwM37lP3<&{wS6l!eStyTG#Z`c|(=rXXNg~!^#uB&ah zNQh3n^x4mGGHWpVnZh7XERnRBHs?~x3E37dqG$3>{8GI*xI%yFt;2_7g8_P${inT( zPD^7CZ3SdYM-_KOeFv~etm&sVW`dj8iJNAY3yyU(X0$x&Q=Ih5F>+&Nh`x+WFySt(@UJgAp*lFcsA9)%6+sgf2qj zzGmpK(Bq1Dp@EHpN5v5HHyG&w3P>gIJiW6k*G^xS>QtA|(FA7Pq05k>uk^1=0u>ho zl~pXGfhUtm0!d7YKV!V_v8d@q)OMJQDzz>|bhv^L4lR*k?-{WELG2!C9uVmM3Y+Ha z-nCh2^|r-w{$2Evf>s$2jo;wY!}yBMi5zq`LfH*2-bof}O0Qs`R`alxKg64G_b?6V?;)SL7m#kfTuhC}F zVTx4jv=)?oyYE__V4y9@gL9njM$-O_UjM zd%GnT6nw??IyT=*;k#x&uH-Ok(x71=HkBY!bKv$n@kGcLbQW* z%BPikX*0&5i;JH%+Kk=u>06Q;cP=D8H&1_=(LI9+BCX=cF?2zVrW(Rwpb;rGA?5ez z^Ph(|3gDuPfTc5J|yHjV^Frlo&!mm_2RUxJ+* zP#Zmlr&%M7W`a){6{^teKQc)g=SLeUX$M{Hnb@(W;{&e2{XUHSctu122Idzg8kHTjJrSHdF98A@WlGx^I?Zpb+{lKjC}Jn{=DVV0 znfC#ImbUW)XZq=Gh#FzAP%@7S5aDb(Q99vXcw)4G+*|7kT^I%VZHdp6)S9B8%CBek zpa+82;9O>jN9tJ`FVKU{@7WmoKj5iXGogXk;1v_x}RTjJ)So>sX?ZkG0d$ z&E8wGsEGiXyeY3)c34Z1AXczCsIHT=MEDZm9m^|IeZm$gS2X{A!X}JfY!&em|Li`B zBYtuJy7NryzH(#L*Qkx<$c>@l`sA`F{O*rey_Gz8CYELwZmodzt+?+-!Y<)Set~7} z1360|>;#P98+o8|R|Rh~V&6iQ37*Do_IOdu9DI&l{p^nXUOdfoH1)RiyoYc))FFi% z?UBM-GpRunQyYbIR6^?*wcyY8%69%;&GCMM-+rfo!Fvj;cpBR0dubq?lkImB9&y{Zo}F>K0C$md`k(A$ z^sf0^4K|?|iuT=Hoo?9XuqS6x=0;?QE8FiQSN2j>-=MK+A|9`oTd}ivr9iyOtUAZz za1px_uQbh+@^k|$dM@-qA!$SrHMmZIBf7q+3n3ix<#?9$ll1d3A)4!98SSx>;{8+i z`yG6CMJ5R%J!>9zIG{B*FGge>fF$Ov7XT&#yNE!}JKnD#l6{1%yC2qJh2s74^Y(59 z3~Bg9M52q|Vm^6VrOx)c9rrumI%1a(1drg_hK3nXoLYh(&EZmvGg`szeDh2CI()WOzS%kE-8eUN|6WV1P zHisjWSn5HGUhnxezLj7tJiBN@#9I523_)o_r&qA%aFbt5>(M%Tb>k5jTOM_Ir=XJ$ zMg&375OEXTQD&r2QJKN}@%!1n*jk^hpUU&qCY@4lM%U`Ouq#W+FV`gIE>=zc%&@pN zxCt{Ok`Kb??`;$Xt$kNp5SlFsLh$&j#;p8Yu6~Z!zNxrZZev|(cEBmG1Ui*8!^@TN z&n~YX4+~wFywVS8=guDyNGR zP$TjVT9)&YP@2pq1p{sTsU|p9_1afY;_OYX{1$fQ&Wc~Jjz)}??qNjaCqH(I$ChxS?#3dES0O(9D{l+GKiZQ1J?gd(o2p6V(-Ult zBpC`@=)13A6fds^I>1UFh#iqfd*)^slzK^Q1R;5Mj-n_}B)`qi1> z6|33@pg!g?VE_GZk+N0p&pci{2)SjZCS`rzo+eY$9XMJb8eejM;@Pk=Ei?e0UtnwL9jl)e&7F z#chP&ddBfuQ{|o5YI2u*KX;j#u)=JJMUs|BL)DBS3;Lp_iNwYIW7QEO4aIuAmYeXN z&1D3U@4O~`>Pq-e@)o-A&Quusv?h7Iipw5v=o~LZRS^eIjeVl332JPfaU&9j5Ti1m zYy#YUJ(~jQ^oBTgYB+R(1vbO2GOh4!*Pz)+z+foDln^>oje3AloUArBH8yKC_w%cG z$LeS>N$=Gtj`4Aukq#)bl74)lf?e*KpM9kKfW!1bY&$X18N{a+KV`vsdg-!jP~(?I zC((}C=5IY*^J^Jr+;pfgYlJVohurUMPnf!U3@6wXiRCLUjk`^BHYqWC9q{si29)I8 zcD~uHlF)Dhn5_N+fw+@Xfr-!6FnEG^cZ+? zLg<%rvRj%tU0cYw?Y1k;(V!-24~5KN?GlyZc>%WJ;x>cDPkDB^bl2fM6%Ii9 zUhUO-N;ayonYSc`su)@|?ODu1kPQr*pa{@v>QMMDeDJ1-7`YA`y&0l`YIQkDvtg`t zdHg9fLl3>dx@V%VMWT|(Z1iS*<>S2&IGw}X*YfqhbhppvroY7gQSYew@h)5S9VsUv zPTCGcP5cqk&_^U|1iDq-2M0-y8+SIqA z;D0U$Nbp3rKnw#>PNCOq7Y-*hS}{#atMD!Z1&t{lNh6C)u(JtnW>wVAkverN!BJP! z$z{c27MGpZqX4Z5o+kDD9ePF)a!rxS#J-17FX|jaNS?_KoLwr=YL0dci@P)l-4?nW zvJKx2hckA%5|#9MGaQ62p>Mcx_O*9+RHkWUGH@?SS0QYn z+@pu{N;xstr9cI_>-EjY#v^zQMfaJB$7Sjqma=D}{ki0A{X&@iq;s`n$_vahKng{p zczSUolryiJRkoyT#;&twy^b%^_ZviSJG)p6Mlgg6x-gCJokGb@euIK&>Q^EbSPfd# zkBBq9Q|dOVB^4}CyZLLr3em6QR8qL2dh_L&%-NaBYyBTM3H~p(@HQazHWhXjpOFIR zavprzp=f*leUDJLQpbySyf@%R$}}qw0k7yH88%1OosLL6ansBegQdl`{}+Vxy-}Bg z9f-_*h<%%443zc-oxHrj#n&v+*qGl@#TdSptS19(vBE(3O27%}I0g%|o(me-R2TzVw02O(5O$9wQKr zI#KDYXSkGiSh)`$`&ys3Gt(kDZd29FaIL$4;wmD07UK(QAVwyJ)vYdOj)kS$JEG3R zM8sBMH9&xpwG^>w0WJs)KjCCrkS!C*tTc-g1 zeDBqC=_Bxmd5>4KJkXqDhh}lq+iHD}eB0+ArI&Jm;LZC&l?7Y6TbSmO){N0ySEv;i z_ev9CDyLGT9oZeHMJaJGgJtk^`6Nn#*7 z(GhV}O%D1zs7gim4vx35&0`MdtB*x~)RD1&aovq)_r|e(8&Sl*99#WvOOvU#Q+TD(3Q=Lw@ui}b|R&|+M( z-ICa-DNI5K1e8>9=xy_4*FXlZqaDR{h!5Uokd(CprlS+~C+E)j> z5-Kf5HnXb9rpV${>ePwBe$S9zobW%6%=mBM_I&RA+;%wGkJ+>G#rGm|HpkB+dnNtY z+0(bTEblM;o0s_?sc`?dt?~b3&t?WLrt;0R#ixUXq;cvsA0meKdcRPytdGq5sEH0k z#{X-B*Z=9BGMN%L^qyG`XTIGH<%A#$Vz7EYHYz{z={MGbPAP zV_XjO?{I;C_cJmrjmcsmPjOG_D<0t)$3M(A9Cefm$H=c=V1j)X8eh&~ag8=z{k%46k zO)P{U?~N)S(>}Hh@g1`e zYDMioF?xF8ED)A0R`^)F9*;2qut8zbeEcE)7*minU5)W1Tvdc(|?s~@Xukf zZsu-kt<-woh+aA94ubzoaUJFosciNi?M3=v8gW3*WYZS{@_@M7{Z>I6w;?Cr&c-54 zc%F%}Lm}n*)$YyJ6r7NY+q#Jty?`8i05k$ZqtZY6ay-y`DjjCAm5wv z-x6lnTZ$*?Fd9HPf>e;Hw)qQmZMz|^>%kMHH-+IHDM9$P+1^D@4nte**SCXqn;^L^ zcE>#kveKW3MJXXpcH~)bG~U7EL@#J(l10d*qy#EBoIu9_JS$CtkvziR4SZ08u(kZ7 ztNBHi)xvjMPq!wLyneNq+a@sji{sNo2j*OB%-S3ocg^VdHlVSc^up8Ufyn z6_ps(a>zA~8~U+l{2g)ZY_TF@qk}%*)Y!KT{q${uAa<6^Im@ya({jf+1ubz1s^UKl}l zLHqB^u;%00rzmL1t}@QbqMFH}3`&zi%^V~3&12HAMd@vBuJS;l#Cl}kmHRY|2!dJa zb9X#SG%(sq3p-*Z7i4T58oVc^Z2)QG=B$b{Nqt{yebtYlBLy6uDEon$onE2d2Vg~@*dN#l>2AJ zYCj3!nflueXYtjg8=4b~ytW%uvPXTVNJgA36@2qsH!qprh-rY3pGl4Mg41*A%8jJc z$8)yru&Yk4>d3=bN5<^riIlOa#Fi}(v8!G5&tUjF&cqiQ$|~|?myFjQ)>OD+5sKLS zb*!a^IK|w#Ioey&Sk)6Yf*i>C3nb`8@Jq_ z*6cx)T&N=(=?QMO7OplXH-C1}eb;BDa~Hjz40I<(jew*1R%CQtciuCfo!}Wina^#< ztHZ_mpC`?4x?1rjJA2=@)V5Ci0CjpYMAMDG0p`PqS1gi_47xDC6CMJUQf;BQ&S87i z2EVRSdyk1;(ueYP*-3{IWuRWhXhhW_taf{T*eLpHseDXjby!s|R2Qj;uDS|Am`}bD zMrMaP-HZ5RJV@^)_W&~+`8)R_MleBRSKP?|kf+LWOlsjzJTvdfJQ*QB*(j?m5V|Ki ziFV8$E%l&@&WBDet5NCbIvy#a-Q&9uRS7SLow(i^s6&3rSw?rT4F2!&-L8~PY z0r~L~?!=xmXWn5LeYz{N983C#f$@j)^|ax(+p30pOFR~Uw$g~1RPR*{V+?T{V7C=w^2PL>-#-Qc9x*HJEFmT=FT=Z z=U?Z9#;%F+Ot1Ut)sK|0{Q7%TU;J@E?B3xT+!5a0E6l#={g7(pNuq^bLm2Eu2%dde zU>*EMkvHGO;jo(88M1o8-UU>KW60~tb2F9cG8Sr+S$6OlE0}rTT4f$$wGUv1VLNAW z#2&Kfg(;^aN#0JUilMxBIiJ5h+7dttC9hnTI;2v&_^PEUOi?-FS31I6BEK%dVnr=R zaX3Ogowi2*jTgaAjp8n2t9U4P5>6MI&@P4!V>QY?ZZ!!OY{1jd>+>UiS5Wcd1 zG9&ZIx@6xvr{%X`28W9x0gK=s4!a+f80!g@RAGIkrh)W=j-oNK5AGVRR=l<@zV%CemY^y6Hzf+Z$1C}Kom$0Ewju!Dgs>H8KqWyz*wv$q@?@(^*lYJeV z;tlVt>4PlUmt>rN7se@RXM$0P+g3f|#hT;W$D-&9jxm%!0ay!}Z& zZ*IVce-n%KUN4q(c;iJR>r;ioH!HjOO@i+p3BBRZ*H0p5z8*@85a@C3wH{u9&2(H~nzmyWQE>S^GqSPvJ6Nl#U)}TH1`x+?; zXGUS`h@;xXo6)zLT2vaiXGKdy_-E+FEW!E*&KrMj0yrrMeZ$nScB~eXq~D8eIwb0N z?>Twja%N**JHcBFZxv&U{&3amcZ3X<=cif(QC$;6ZOSUI2H zaaBz^C==pZC75?t5Ai1^4%(6mn+Q|!Nqd>jfv{zTrXl4Fq+mCoqfK+-U||LnXfG*Y z9P``!ov@enQ-STzQeXBrudJVYyt`ANE4q+IcBD`kk%5m5;2pAGS?cN=-2+S=qa?e( zDbc8^*>p70*>{MG1hIx4>XFRrvA*iHo+Y4FPf_xC!65vEUrkoOcrm-=qEt4x!|uZ3 zV|mlBUb5STp;vm$EChQ|7Mtv}_jYGPrtUbW%wd3``Rk4${p=|LHsbjL(_}HV;(__@ z^<-qd78ZUVyV%G>F#w5{k|`Y=Qg5zaDm}f7IVs*nk9L>K3Qlfe@PD85KQrlSW9cDH z$$Rojdb$#Q_O+}EMmV&z^CjqLmW9ekJqqW#w8@iCwQd^O<%K&7ExM5@0`HSWcau`Y z8mdP>e?^qX4#aIs6~s2@LWElw#)J%rr;%FKHF{#q9HVip#;WoHN76lK?dO@F;ZeZV zK+kAHYU1)P75$Dnq`2_r_1I}hYNc#`e=g!Nx}Djc<&Fo4XKIt$mFPA?|A2S&0|r`w z>sIsHYmuviI_T0)>#`K2sCmptC9YjlSo5g=q2D-h1Jjqx{%<K&DiEG2HU z#-FY{TA8)}^WIK%1J##eXIA`kgetGY+(YMk(~3 z|J*z+c`~Suc@n(hjCQ_Z5sw+kriFo_Zjs>?k`_z`S)+q~Qc~qTF8hMnMu1N@g-%be zzpduzZkkrd5AXTN+30}w37IYg+TbN}`)F4Aa27~T@iiShMsNHD>Rx0tA{Pg04_XQ^ zZ_QlCUxNzx`~9%K*(j}U82Z~8GOC{`iIIpd_?`@N5N>q~U7TU{YA`Yyc7 z@Oh$o&6ESBBt@ygDEGA)@V0>_ZQg6@=z<;)PG-M>r(31aPd2gV>*^`x>szW*axeSF z#Xbw+ARS#~^!8rN5nfl?E53wx8cpSUs3HMsE+W=V+(n?L3@rXAiaBHR`JV#RVwEg4sTIy;Yj-Rr)dapA+s#U5AA>YF7;rOTs zSt51mA@K5KzJ6aeS)Apwz_WU^5vznd?_{>}igL3A&ZQ!cAL`u2yM3hBm!J};7aS19 zPrhMTp0RoOGBy6^Dw9I7lmp<&d3cxV_0!-lP)YFB(R3JkJ-NGU^1@d=FtfS&Ls`cH zw7B11<;G>lVAbNt&< z@L$0g^sX40_l@Fo8###X<=T*rNbRl;(H1Z%pNIW3cdWL}nPyzi@skoglu-8YxettM zpKHA?KI_L%)ayOlm(gvT*^Vq}>Cj_9GTU#-fCHYqkuS@KRa&C&tDVXel((bU_Ztm(>^RyLbH}39*_(meC zbnombE=yq5N$Q|saaE;l^ptnXbnprtPd7E)XrLqh;B{~vsxJAi&jCZ#62Zv)mL)Rj z%fr5`hT1=OkSpM$O0yN`2s|61*QB}7PN6Hq!dzcCAhoUsIjr|_*&jSr z{RZl`+CeyY@nI&n5(*WsG?TwX4?<{*f(4KG+M!v*q&)OMETWmEAuG8C5T0x0^#tR% z(a3*KYJ3tO_bQc}QEyE)x($?)`>e)M>68G!JJKa%Np6a#>h^UzV?%BA51}sp7xO=I zT$dv}`DUjPGc8MKnIWx3AalxaCAPpGd&|UoRt{f}69nGTnO!1VGdLFIiadZoG z#Rj6nX?0z`o^IR?_;;6CJ$s30jJ#a61 z&xaL~<8@8!WjIY<%XXKDk`m}4cayqZuc~=Ab2LGDY)f5<^JaZB>Jeku{P?szTn~A2 z8Q^8K3%P4ePlYj}u?taL+--dbeQ~9!eXcdT4xEQEF-raIqB6-J>d|JxhS>DnVH<~c z#CgS9A3R@;?2RCu`N>8W8tv+O-ytg|N^XptOLoo?o;~po&r)v_!2}5CZ}uUb1%acR z-tX>@&x-(?#T)nv8(KewYAR!z{$Y8-=_-Tir=Cg1ILVu)6KP4i*-eYr4_^lOP7VAIT1VxxWyGtsu54RRAX#F5GfUbb)*d zIyjo9a7rz}jh_axc~k7lD7B0}c6!>z7JEwWpSSK_O+%m_rRO}mSCa$G()XyjF!j#i z-L00XeGajf1IimBvB-X+=L|1cBfoPjIylsazb#Y#^W$6@Mw#%zj_xcZ={n&UN@D;R z-$Wc&EVWusUt#E9A88!+-IfwDy8B~HsB&Zv4PaVe2PX6607CM1!ld@kUN?(x1Vwk zQbt{R<t<#W^eZE60wKhO(Y^0y z0ROVRaoW;?PCHxo)CY+-q?QKBn4|AF>`Cew0jHB!Hvxq)t;O)tp%o8~^DO^r1ro(O$94v>%ilKzxv;5JS-nN+#s&ik)rq|W^P0HNQ_PiM6ttAqf^8tB z7eBnGs);2lnWCe?Gunq;+jm6mBZtR`S_=w7(v=TKaowNQm^c}%J3MKYvoWb|lqDHn zkD`2>f^}a}YI{&VlRNSD>gGpvqk+?P)m>wJg^OKho8hxDZV&0d^ZO`djGJqY4JP#S zpKscVzLdSWs}E2{m!z(qP75{LmOP6;eCE?ubdWJ2DDf%72YW9h$#+C_HxaY2zq<+Ryd&(Bl591)c!*zY2ubyC5Sl5rjkiAiZCqCuvFaQnrm>0E zPgtDfA`Gh*^>~xln@qeAI8iij%S45ZlHGy-p!ZFweg}JEwB7P>oRbzrgIcU>AC~XrSY)fg;RQlw z;;u-Bt5vym`!A5znj~QA!ezMOgb~3zz6!8k$^2=ZJvs6}JcS479<pi*8Pw-XEnPwDe15u)az-p+G!|(p`CECH)`=YK~iRymGh?~pW;L**duBr zadM4xb*WmZK!7trY+0Mz|g zRFd}$Kb9=1mAW)`>NaWcZxdN%PYadCj)*)U)0`h_q*S(Tg9|#|Tkhi^GU4;6Ymru}m~@(rz{)hcu zoVt}0axe;n~-QLFGbwXCS%j8=}Ks)xKr%`7bT33Eo=5 z{@g#>@q0hQw7Y2|rA;3kf7c39VMF#NXeMVM-)nWA36DL?=7jn;{9=@T9XYN*6Yk|Z zQ_`Nhqw62KO5nDsnu1u>s=4X+aP!LO?w&GAke;G?)`JIzqKx7q7PZkD z3^n-tjl}Z4^sCWqM=vsQD)a)7*8L@vh3CxU@b22?`Y({k;=)XMlTyJj&d(-+()J99 zR_u7E9cvJxduTik4`e2a9C5p{P1ru!SH3pvkT@(i)Nut$D-@c82V(#qVjMeFk3u<_ z3>wb+cY18w|ClS}+=nqEm1yl_F6k8q3sN=Gd=zTr%(H6)e*~FLpTxeBUvAL<9=U|G zkHZjS{eQ@N{mp}Ey5s8zQ99xTi+t!AmtPMbD3Ub}SxwGNvIwe_1Cb54`sFrZ^xb-L z3zeK9RvXIrgly_u^C9G%V)nCC+X>sxGmAU30SWp4ljeZe(J^PGlJ~Q9B7x~qMEUji z=qhN|S@-q(`*4VF{UD5rlQC7pG|5}gve^RCS|Ks2N zpJwrKbh)h=(v6ikikW~zzTmE?HFJi1E0E6e)*k>f5OJ?uJG8tkFRwRl0*`O+vc7a@ zib%dWmt1A1LRGaeY8xzGd|oT}F5$M`48kxPR$SUp=AHL|XIh`$u-j)B1JddJUy2_Z zi8Si-gUt>V?H$Am(Twvf+02F4W3uM|lFkV;;GcCb#Iu-LT~^T0x3w`kR(2 zt!l|J9%;}}MT98r>eR7H)ilifA|M~ECTyKv=5L8Yh&p|Jut~Lr0^L5cw?6FT(`dig}2YP=F=_EdDII z6o8prYwU&vmrTQ;dww_zHmNQrLVYgoZ!esk=@yoLvQI{Tx*MF>F=vlJDnnr&D9-k<1c3mjuAn z;5RmA9 zZ?e-z&i`C<3W=;yOuRKYQ19VKzUrqeiSCTkxF~INs)UdaHeCIQHA8;iu@kvB$GeI7 z59-fjz-eO^cpsL=-G~v4l)C4;%*-lIlxRvwJolT)epyhnytIRQ;2Uz(OS}A-NISvo zju-Po!0L>iwR(ap)|Dx!n^VJ!=;!Tfd7tV0lR2rK(GHI1(3^)ahsFf=d^6W9C(fbI z13c2+pB`(qO7*=1GlyVF)~H_bnl6t87{u>8^YXkAPe_*Axf;-9sOnDNhBelH$1E--BuU5z-s?PqRaLouHO`z z_oupO+xM=Sv`LIUcSCK!uL2MQPHy*QvA+0T~pe27#h<9UC_=gKJ^C!ukw4q?KTI38}MHQbv zO>J%szwFMvea#|hoaU?`6}L1S_^MLYt^$FO&FzRHCXH%kv5~EMYR5Mzi7J^*G@8v% z@IqOb<^jIUn&^$-eH|vt66!xw-Au;J-xb^RBks|LiP27$-gvG+`FCa(4|QvmxFZd@ z8k67E$^&&qI8%|kI?{NRHPIh2N#PHyC#@;~HQmS>uJp(KV|uAw{LWa-C3HH^XheK0 zVt-9^Jzl3H`UEe{?aL>_@eR-D>+y`xg*bQmoTIF7RYRSFpXashd-Z4ITp-=z@L*{s zeIVH5k#L4&e$6(*gJ#voGKPPc5!v6*zQKq&DcS6dbJ|{6z+2S&8H<8Y4%t?IKQg9Z z1=4MVSTlR zZ&$)%%~8QY-`$4bTVfBh578VxtIyePH4}*g6EC#%(fWK2n^;f)eIbeV)@KN4l3Pad z_^ZzuENHixRPh;Vzk5A2;n(%O$IC?7qWUAXbt*dSMzn0Yc#yZr06iq|ooK+HzLS>W zT_FS}bP;rA)PIL#o9VLDnZg*m!^QI{45e&#%w`al^?c{m7ZF0+l*}nj5kKJUd9lrw zR&_P}Y)z5#$>M(z%lJLkME>5$LEZL55#*_SD(Q`YT>-fcm(8jZR_q7T@1Eb3Zgz70 zc=nhvGQoS?HfhT7j^vKDU{K`bfPO@?Vw==USZV*=lTLWSO=zJE-G#|tAcMQ^s%cd0 zUm#m`>O!aqwjyC@E?P(?gy*2D6=!GmOyg2Z_-vF_tx9+X%hwmET0seV>LNR9ucRY0 zAqbnsOoIj7^a>i4;opp9Up^j!?3BLXuBKE^xc~;`%{FNkMfM;~e}v+{ScYG0WA_q# zjT}exO=!2XBsIP*Qp;zqhv8hr=Ug~rx1#XZXgp?8R;HeJ^bLr95NiX0_|=*pM$0XVK?4f2nzotf%;?G$0W5d+OTi-y2{Qw zegr0|ruz$^24sL>IH2l~zx+74kU@MkQm% zyVqOZ|NPdO3!>ljol978XpArM;sWz4q1>SkLe+i5x`-_G4qn1oI%QaoY&&b1z)S;= zf6bVJMX5gPyJv~I4aB0fWrS_)WA>K`N`{MZH`dAkD0QLV>WHD}(3BUdpD_u|ia~ua z_3+n3{JHc}PYOu_4sd(^frsNtu#^oKy{E~;mN=WKdqFo#&fM5zYV~vqc_okzP2tjI z8REm*(3Wv$&rNgt)`#Cm$M8m)Dr=1XtlQ#w%&4oXit$ru=todGj&F9NH&zfPp6GZQrkY=8G+I|1MPsZd^&97! zi-MD1`=}Vydl-pCg|kV$@NpN`$xH7FIhF$og<~l;ztF zzxdY_j1m0w)`mvdb*2=&8p^+`S{cv_w`yuhQlMo~^#0}>7m<|oGTbKX$!Te+5#%Z$ zgbBSEUeKNSqw?Bxp}At{*rVI&Wi2J0((Xhy8VQG9)auU~{VvYB8>+&&_{?i26P$YE zph@^s>(z`0+%?x_VndV@%4O;)j2}2eq}+IGme@}9<(0lgnxtcUgAsfs_cFj82z!x& z_svvdo|N5TV+gvt(Eadi&kWqdG}#J!YBNRBHLMieH8X~6%L^9WrfI=A-%rtA+16Ua zo&_x?;sK%Pw0kjM#2r8ChsE0x-Y`iEPoDHAtiGxU(>}TUz4oO?IinWyvV8fteaC7e z)5C)eobHm&)Fyz9LC@cpuo=tUtEg1!L5XZ{JiH!u?vA&+<_QDlLp) zCt-@02^t2TVf$~b7OiuhMTB;lLGOv1#!CN6@Wx1&uX?JfOf;$7Mnf!M54@$@Nw0$s zM!9^X4~w>-17;w;!%-FcV>5=Q;We~Pp9tKAXwc|IvKrS=o!3f zk&<6^f3B0;{SyM=+B$gCao%VUx8c}=JtIVCDqk<2*eN*^7o}S~&+((-Q`<3!_Hok5 zYS8xX&kK8pif5HzV@ILI01GFk$()#Ak4E`5O&M2Gbnaw*$zuM=iBUwH(QjY__5XK@ zMbcTvFyY7%GFcN(Q0^y+GS7kz)I6b|7mqLGXto-`H(Fj&_-Y~T;*HXTxr=I1EY?7k>t}kcPyHVrZQ}U2 ze{?fMI^4jQNeZjaX8@2P2E*R1>mQh{1WWHL%;$uI6JBGvKJ~|P!exv#A;mgy|9nWX zs~h8=oQ2%3d;@jNUtlXmvK#cn>XjD4{Oa0pd?2GjohT&FLrAYCI;{T?!*-VANU4qP zv?K~iF5tbtwi>-_fb+AOCiHb@XN@68r8sw}yFm7lXPRPh6&7(-VQ4{@*~#|QhuGL- zBXqaSvG560!Dv!wcc0{QYp@>gAJ1}b6YnpPPrflbYA8s3I$fS}`&wM^1HG8ZT?Et8 zu~q@E%a?Z)(@2{#y$SvCP$IsLJ-ul3F#(|>=ETjy*GAKmA2qz*8uTax-L+#&6TrF> zrpO}2*A0bGJ0(k3-UerDBawzi>2V($Yy33c*04v6U^^==JqHdB{S+iOb!+K#tF*3a z_6iu~+or}&@tdvAb~Tiow*CU`Sg#^vJbjN6R}-`uA$a=%vibqtgqKfY@ZBPYDmCY4^&K5r(sM} ztdrbLey#pYl!+|14+wwpZ$5aEnxEL+*`bAblkJkTF(W#6o55ON&x_4*w8qO3ee5vm z6%)Qp6D*-T>^AtW8GIvPvIWhFJXauz(0!{!_{os)W60^IphD^CtXGmZp zgo7E4%W6s|_huEh%2Qs7{i6|yY^Gt)(3Mvf9kuWSf&shN6_H^Amq$;Ge7W>KV5%3( zZ%etWYG&YO(Hbv_Uzl@0nTzrIP*5Ol!4}v*Otd&U0u-6%s%`(MY0W*o{0pQwMtvAK z+e_mlTtl2+_ZC`Qa@}yT1^Uv`H2N zq21I9U%6Dc<|qNW_2*9}3r?2{`lPTVAhSDE@9ozv&~2%oTLyMK*i8$zfg)#g`hFU!Z< zhL(J?p}g9t^7K?Rz;{rWQ zk`#py@n2VK;`245w&pI3_owlCS{pT9Z*H)#9;tdIa}P4KVFGUb!ta9LDWhuR zcD(nR;qq24tp=%`S6B;(*U^SboK9!`OdV8oKB04a0;wHkCUqDsztd1oNWwgIw|};1 zm4_}T0rbU#l7&`Rr3bXvnxlc(-X$&;A8K2tO!S_w5e?fu?i8Nzr|hRf3@GkSwvu&p zL%AzaD)?$Jid2$8utQwP87Au+qAPxVfS79VAr@=Iqt&Fz@a|H0=hYNj?P>j=U2%)x zQ<}@v_ZYI8NHD|Go*HEd<+gsizd+7O-$@;IwP)$Mrb}ALYbt3Y5mpd!WK%?%SznU; zPG1ighUB7J3iX^ zf@v(LDz@WMF)DnoB0#RIzeiT`c+|@>sJT(X%b5ME!y@JMvuQ!a#pC-xa5`dNUNrv6 zjHHw3ywqo0dACvlc>bQEiV`@l#Iqy3U=wC@>EZ z+kMwf3b;Y@X?D@&v#fLKIUQ<;v;6XWgZxjqD;}*y(y=da z_6v85-*f~Eb$53UaoBP?#Zh3LN57)M9p15BYIz>e)=aTRa?xVF`?ne8KYLgw-sB$D zTqde6EC?W_r#EM#T{=76Vq@$*Q5*)U64za|ozA47Gma2X5~aE+ zZaWRO6^cW}UO%~0)(D)LdiVoK!eVaP?j(di7g=-U+=_UUI0(l7QtYV2YKi>&l7 zqkBHgx39qVp)cETs*Lt=(?9aj_O(|i=|^B=i%I_;M3bi%sQ_!SzKA%*pZ%S<=%GFxK{&Iby zA8;O1xjE5S;{YY(wk{840D|qViuz{Nz(T=o)3WWlO@a#Q)PH>KlNtoyG2H73A0_7p1DO6XX$;zwfIserL4>VrBCMf!6aHw3A5uAuE{38d=Hf{9@6FlUG9itqPhlNf;)Q$ zCV=mU%s3F)&Mt_MT5j2m<-z>$w{V?44oWZ1kB& z558)gKQ#@@x*DsA?RPqdz@FAS;2uAq`J?bkFCS|nC*wO`7CPKNCuTja6QSIa-GWjmxkR_vgkTaH5T>tu#D_ zIXBrUAP*`m#`NrFbKl59O+>WEc~weuSO1_e7h=eU;VMo(NTtj1&YdrwO|sB}%%~r6 zw-5YZ?Y(7KT-&xLTqGel1cJL;A%OtFCD~XAu0cZ}SOFE>B@jsP00Dx#ySoL~LJD^e z?u8VPUfJE}?ET%&x!phdyFc!8c;Km`RxO)z%y*8t#u)FL#~6jDkGW@&ZZYCW+f-f! zw@H}2p2RA2rma%%rc%O{ky0R`gw~oKs6K_MfcIHo}N747rm~>!^jPb5w^&Ncja*8 zFMEPTOO0;8Wipwg-(Ix)W5w3Ipk+v32nF#fL8%{1Nd@C`n4LYEEAPuJF@I7zedAdY|KX$g3k0Up&o4DL4JsRLS!V_xSZ5QEQ zD-BYq961XU-%%*!WbdBclzcIS)4)*1!orB1lw#Eqw}SNG$TMpz>30ZSW2R)!L#=QFDF`%kSnc}Y5z*|_v&E{C z=pf+dzAq{pC=~yTMTRe3byZDyjRHi$wRl;%kx&j_yA|}FjlQDVZ^z@CO?vq18Z?<* z=6+xJ!!`J_Wt^J9OGVzH!#E0C zT~yxC_fMu_yXt-B5YG8$_Il4Rp7_znXQHm5m5js9TiD%M?|~EbJm$=68vWRozZkE^ z+y~>mcjb#CuDNh7g*ZS7Cl4BR*&gveIio$2R+I*5l#QL;vJ-z&DzB*wN_1dq0+UDY zJpVAHKvdlHbVyX|Se9>{%=8bGEZR4=Vn>3T0Q9lp(7Ym#hj%AiaKj${kZggz^13n4 zrLx-p*LjQo$YFf&Oe=P3av$mfCF>cT-@MN=uBxetvZSpIW=X#2A5Bwda2znnzu@O5MA77%Lr<>@6akwCZ^Y+H z2R-lCF%H4@>nDvPeTmP0nkEjM|_#nw|`<@-*c*)Vk=KC#h9uS1$B8BaZn8tyGy=u?kYssM9Dl z;3_DZE9F(SuO|VVdOhFwMDF`lsC%VJzF1!&p$aN=56Qg;Xj%OPmCxOVn8zV}*gTtC z7k;5ts#tdQST_(bepTMk>-Psvb&m|$4_Ony4#=jiABGhSR$2)w2CNq}Y94S#$=okN zdE>f1(Ws{Yp)jqftPNgVOpfdSbjq3ElTOsZHKhD}UDrW`*cB z=lEwXSj7!$EiOD07>!!=^@#QrukOpqJZ3(jsh!&<$0=^a**13K3*3TUC}7i?%n5eO zxRW;?GqWjw)ZG+Z)U0UmJJ1<1t+H6I-G;3g5S0|?E^aFn=q*Yyh0sOsqja}r=Cjm1 zaY*?ll=Ul)3#_19LIAeH!Hu+In$JxN*X@Q%WTv!uiTyNt`g6pauf$w0 z3R(yzZ=6=~m=S;gSAs>It2us9=d=v_oc+slO0%L%Oli0i_v2mXj@x_JH&|vp1n47R zK?F-{wZakXPMQUX&mv22$>HM{aoImX+^3J{wxEOXqsdB#qLLz80wyGNHh-444g>4Q zH%ZYjzS!A?!9~H=Q8IesNrb9C1IQ)T?2VLAx8PaHQ^}(U#Kz%gfMRTge(LN7@{DbL z`=Uj|99yV+946*f07%~P`RpkN>2~EJ!qa^KUYs8^!>y@9(Q&rV-q>|v?Jd>*AQ(?r z_z6-OuTK4}yY52b{?^r)lVHb!frNfp{-b@odA{*i{yM38O(UW&EG>z%Z7}DH zCY8F$Oy0^!Lccwd5!wYZky0MwKudPD8sKBftEOyQ^KvpXK+Jn1@sBi6eqZnXLvzOC z@Pon(60P_9rI(Ectu54~6{9QV6?Gn3i5hNLiuAXu8REV)hOKFh1(y+;qY`C@{9pwO z4z4WXYhP@G;w_oWpu&RLI(U z+t(NqM#gh%jxT)G6n0f9g+s9`WTz}2gyxH{(cZEHBqu- z7K0<60;P-&@EGg6y%aa~zP4pd`wPQ#v$Ne>?_4L_lRlfrLnP5)T5js)ISR_q@VfJS z_P~&Q9P=0D@JZ&+25r&ka|H)vJ*|_a<5t6+|F=w-toOpYtFv{DWKA6MXQbS?L>t{~ ziA+6{u-Sx!L@`sa2K3_1f)_W*Oh44TDz7u4aOyxAL6V;;LS;faToP(OL-~dn41r2W z?C}9E)cs0g^yfnTG5T*<*=GdzbsK8Zp@9A|=|J&If$i(&5Hj>-uM8rN)(~b{xa!y; zFo5x^4o#hH@^y+_)cE(y6kdb`@|Mu8Nk~X=Q=ZP|E3Vp*@j=40IMuo#a=hd^2P!!? zrp$Y5cD-x!+Vm}Wsj5df$yMWX9R&*uVQM-D+C2J74s^lN!>{eydj$0nnTiogb>mI) z=}WHAmlds*wX*f$L-_kSSEO0NbreeW?`0(C`u1{NyDp5z(Pye{S_`R+0&W!Et%eaV zUeD_J@ULknEDCjo-N(Psqr!t@*1jv=7XEr7WnA#uK#_DXvi*H{->?wqc*xBQj*)YN zRgw6rwz?(?0XA(;Hkqa(^EF}M9twZ2tp8Z6NR*|dqr^hjUutVIqR7j1z7*nN>f@ zHvs<3c~DIu$Wqr6O<7q`6)#93B_w*SjkQvW^8?`VSiN!*K?lkzD>_@;(eT3xqvDZS zTTw#G?wB2;O(NMwH$;u_QjXR77UDQmE;E%A8G4R9{0MfCRNGokV2+~H$bWPamOc82SP=369v|Z!irfPZ2XfL+&aX`@CAvC41XW$(6 zdIbSV#j=D7osuiChQw_-tC)*dcU*eBtSV3JA<;F9GmAsGs1-*uVv;{y_al;{#7^<2 zvWTmH<{flL%q)JU*)V;uIdul{lC(VCnZ!4Y)g*@5`#sl7n^m&6=Q%HQFqqSm$99;P z1{OH<+V6AzXY$A%c-T{H1@>_9hBy4~V6xjsU}V6}hgB=)9XKB2%S~G#%sp*npzu;} zWl%WrRkuer0YTU6@c~cM^9{RH6|02G+JqZvFYa|fiDJCyJegbd^sX!a_55w>txKeE zYuwb~o8yu5GyaG)*SVKd=LXNeV-@l+Rc*4~GXPij2VfgW?)OoeXPf9-=$eHci%8k< zb}tT#42a~F(AR#Zmn$F)&07QFRcAS_EHYznrf#$uwTR!#+vHWf@1tZb#w4AhQxaG0 z+gA7TRz7m3xb;y;PI8}&;mVqIbWcuP;&RdB*m*~~8#C)2fD$Rk(iTqf`kydt=-VV7^q>qi0GhO+l%~#G5=Lh~=Zr1B3#i6*ewAy;d z_wVHI8h?Te?S0r;vM4C|qh!vjiuseCK0!%&(uo_-z#jmNS$u^OSAiuxcvy4evxIkS zU&Dx~;v{$kN%fNwx~eZ-TDsAI>7%D>pn*w5TfL3ak%s$a=h69jazy(OIo8|*IPnQ` zZ*&gE9Y;}L_qK5k4O3wK$RX4up{Cl0PF5!eVA&+w*7dH;-dQw9*k+r1Y^)6;`F5EH z&xXhBl4$w^CaZE|1>@8!coo1e$T6n4>2Ejgi96>jXCXNsh{@9Aqt^$ zKia=uc@mvUfgVS;gUr!ptM90OBsk{kOt4f1LnbC|KdSYo4@ycLnID`B_2}QSaoTMA zbbq&*i84*tXI0w1dnJIFN_t;-Mc?sY=7ZbOU855b2iQZgeku7i5THV<>B137Uby9IEtiu2(R^Ucr z-pR$#*Tf9L!C+A6%#~hVFR3VEv)XCj#}G=u^67>jl3Ts1ht(K#PHabz{x)4w`CBIywL5Z=0XUWgAdif1*Zpwrr1p4fXpr$o$2cmmfsuKO3d}Dv;>l3R6 z!34HUY(tWmM*F)KjL=Q?kqwh#AhA=rpNz*qNEU0A4>hLKl z6WXdH^KelK$^n;$vC$kZzMf-;VaXpqz8}t|O*yx$M)#zg6>k*+=PqsA%`KRuB?w-0 zdKcXzKHU=$BRIX`fb67jHrE^v$7jrR*do+k(ly3+5WglPo6vp$dY;E3 zg#4ZkuTCYIzia^FS4SrnZz%-nV&+r`4wz0y(tD1swcdQa*fhU5zL>Pc+)z_l{~xG zDncdkksk?2(AGag1lf4Kb40jcJthuI=81joHtVq1fVtX2J!muadL%OeTxh_2*cZ4X zIPvO3;3^Fid&iX%o}$b@J0YIR-K&uIFJtQ;1Jnj3L8j3Pnun`yXLETbf^Kw9Y9a*a zgjutS>DewOe&RgGHk*mhf&l+OF}h>)DQ^cy1fqWRMW9npKQ9U`wd-NG#~jwQ6Q}s> z^-Qgl9l-$ExfU5wrz=Fe+<$pinXkM%)|neBT;DEFNW?DtR!MNjUJT;$Jrb7fDLyu7 z!RS_ec4ihp!X@`=|Nc~sm}MilBzURx3d3OLqVi3XF+m=>7u4VSJgLvmqc+d883$>jNNNCf8Y zg>GqJlQeO0UYcxOLT7Pv)yuXltIl=S9i@jlTVsuh(_A;|xfThN(OVX?6QM<%#uMo$ zH_O_%p=r@oAAV)#jOP)I8~s|bh@ei~og750Dw-{6HjLh=np;w>JLjBWoSkg4tr?Pn z<`2{(N<3URL|+uq?1{{+yqy#t_!y3k|1lQ%r8nNbQ~vw%igt9${MwJg!lfI9a79DJ z@a92>a-^-vIQ%wczLE8h0ne^!Fb^zkZAw9NjDw@p#<7^_-6ypsTn4DPJV7_!6@<}Z zQ0u9GweyDolyN>Fu71@zUaHv9a93kgs+6-CSEyWQRond_0?9sog&}~uorAW;?hqDo z;coA+Jv{V2R(ArCoZjwZjuWa&NaEKm!p$~#rxVw=v}xPDza+5mDg0>)q%rf)V%5Kq zz5G>o^A7?T!9&u^R`sJB_3FUDQ)!U00Al6)^XzFM<|QGeC|2r(k&M!^RId4`9QjGCdH03nuSL+_sn2)W+n6mVwKl>fzSdSE#7790 zt#!=(vG_)jKXhzII3{#bdQeSAiQc*lbn54hZ5N(X;YniW1zE*$={VULx0-Z!3rlZE z_U{k4AP!r){M_T6`sLmp!H*#cLRUYeBJgCOnR=2U*+|v-5yo_pDtl;EMEHBbWhdA& z`7%hm?dIg^OQNM#f(ggeXv47aSU#|b1gOP3|M+>W~^X5uThn=MzgyI<{ z6O#`1^_M4NRwBDGKEYtlhM>e(quG#v7g0rf*^jOXP-xvX7W)rjN3B=h3|80N+}%rC zCPJPztA)v2TV2EnX0eMDACf+s#&pd`(yXj|Wrn#y1Gi1Cgix>N1@*a6(IpG7s7BfS0agY`Dc*HgUgGR|}53$qQ_Y)L%ZfCJ@ZRNsiFxO=|6~SIy zA@j}>W0{r=Hcr%csodqBQV%H}^0Gv2d|hY3p!vp`@2&Jw^hKGBUHEyxgRucZ8r=1_ z?*fmy*hHgq(+Jpr91%7^E?#(MRFb?W+!ur*3_`p0DE=cQ3R08$>FUlzFAJ!7Nj<+H z9d+&K5m+RxJytxA{UH8jG;8dI^*B>^H?3V=OmDB)?s#NvMh$xJFrMylA{3h`q63Q? zKb62rYQLD^0IV<*3lUp3r40%c62-O0c;H}IpJO0~h&FfOFw}@{i>mTj;7E(So{T8i z>(yhKuazd$`1&6o6aM3WwF&5w;`n+)c>g9sn!OOU!f#I=m`!K^xp7UQH?sJfEy z!1W%%n8cJrN#ij|u#=azYVA>SZ0zK$bs)wT+~6n3ixu=Wl$obCowI#N{GvM!=jf_Q z$^=6BtdPB(skxVnK6(hhA?cA4u9t|WUNYElq}s+1*)iJ^MjYq#Y?eDt6pIPwH zrH)?N*VxsiYF>}L(tbdCK;JD|uMy+4HTvNOj5`i!V75L=lnJKr*-OVxH}7zZ;CT09 zd5c2It64aIv$8r_R~dCTq3V4o5G?Ox86P=AnrR6b^*GvG^2?iKGY75t;8^y~H6=5z zivV$CGBfdwAc-)Hh1^?1*h%d=-XDN#%hd`yeY9&R3_tfW z$E&VN5Ah`f7fA=AI+qF17_rya%1W6VrwF=41wVDPupl+uD;5@%opSd)`d*gV_}dM* zbH5SG3$HNDQ)>vRHS-92PtH}jw%|shQl*T;{Oy95J_yK!L9ri6{7PVwr_tKsK)7wr<+^10g>>8^s7 zy)L9SiG$uJLJulw>^oDtbF@{X_iw#v*6}MLFhE%J9Z-Cev)ehVAfAb>veaGPJAfG@ z6D~a;$}4|&v^$~rVl|b-(2|;VtZG4=!c7bEP3?RG`;|O+U$Ty2Q_ul+;jS%~^(uw> z=)(Wz)qcgubanvJ8NZbW$l!FkycWthAY&SF471%3Sg^XIt7?2B3#Q)tqty@fM!uM% zeyYGItd%GqymGF6Ba!7uj;LHsy?pif#nFz%B{BVhEI`M<1ol*<9#MqsUEx3*e zEVq0>9v&|kXkPu+INJUI)u9)VWcmrxc>|fHL0ok4*WOLQ&-N3Z_&imrJ27bW?0B%e z?l4yDO6l{?)!*=FUiFQk%0zMW2M|Iiu;4U z*4Y!t>YPYSW0O!%x0f^oi+1#eqtjLU339H=8HYX3vdhy{0ni?#>Gkww#ppi3tuOwH zS>{X0CNw^X!(LuA%4&nqsg8()Z$Rvceu$uFY1Qxr!A<8uWXtjTajH}oqr2u;-KyDw z7a=nlI;L@U8-!60pN3~43csqLQP>?7w!66S&ciYe6U=!iq@-qcRk zW?<{{|9zKdaT zD6F%5BS=iX#9KL#8arAA>0t51t*i4J?y4y8i1W#u-F~RHo-~#1J$ep{ykH_iV@(+l z_1CJu6*c~bM6s+E^Q9fn6iga8vlGI###}mFc^643THAF8bv<4vntse;% z%s%V*3Bs}<{|x6Fq8GIN`ly00f_eVD&5V}DZkShONvvVH*vaMFii{gQ1=I%QWwvsn^OkZ1U>an#= z-h?hwyR!IeTV!VY+h@(bOYY8wDt6l7f^47qC*fAVxWgC2x+8eHijtc) zff-}jQ8tf0YhORBB-lq(4Ro8Xvacv-`cCSsu5$$8Gtd1mjV*)cv!q{g=TUlym=jk% zcZcQASoKl0PjHzf{E!*Ek0z+u+rDxyd;y%E;Y%J_WXECgBsg92>|QzSV->>+>{514 zS!S%AQF6HFLHXMkkLxI-hapzM)Qx`QCih<+X@7E*FMc=f*jXC|m*3#+T@SllNJ{;d zgfeUw4pvYEn*Vc7a5oJbbMgTr#Z0Z-7Ka;4{{C3WsPuGEFtIyVs1~j>1#=TK$5@RVFoPROQ;gJd#VF&P{TEfk}BRcw3;dgv?TS)o0QJWj}Ox6P!+sGe&hAc5S=9D8^*Hm%SKo?&V-^=YV@dkmUGSMnOu+h zjW3C$T^PjZnfS={R+GlBz+a0pjw5M^VZ#F^Tc4Y?{)z4h>E4fPJ5k6J@tvU45M6JWSX|{EkL=(ym7Cf@uC}N}B&{ zA;ges%=1MqS8Blw(@@2ecWQ&#az9?&L%-Qo3kD63I&yM%Oy28}uMD4@r|ME?EI(&l zk3LXT#7(q>=FRWmciqL<7gY2P>%{2q-)GsNOnLZFUd(EN(Cxz)QJyRusZ#I$MH5AY zKUs=0%MegVpQ5#&*my9PbUIo6<9}b9{$q{$k5{&x1kKp$HwfX6;!c$@9Eri}`48;T z#Uu;A{wE0e8{{NSp*;!=SdF%IDnxO#xp0#mas)S$A+yZWcGb7mHCMpCbmT}K#M_%0pPC|}g=X&m@lkdD$9$*7Mk z;Zo@H+#cQ(Spu0y1JYZ-e2hxpRalr2kkh6P z=PTsY&XcZIahzLj*?|n>9@#!q$eQ_otw5Zv${G`^}9K(Yy@B zbxk=DX*N+pzB=yND7-phCShE|Y;$6+;xj-~INJYQF=m}n?Jq>ft3ab=GC*UmXfZ0& zc0T|ARpDGd6s0Pa2ztEN!T`@4T_0$HQuYx`_?n(39VtsCt$%2&59SYM3{xPI#>6T& z`LLtRh)e+0cpqPnt)oQQ$^CkxaF?HVPjdTq<7WFs?nT^b0eyOPQ{a)@h`@Omf|v>e zL@idIhNJlF3qKZ97mbGNlMUT68a2bUr8fKn-ijo^kOr`u8wFscn*iFc&As@v^-EBj zl&%Hhc(fF>75c=eswcZO*6Yq%01esPIN?)0{}Tl3Y`vJt+;@>UJ?6eeSll;xeQc^L zU7fU@xhovJa8I(lf@}0cL`#uIiNi?fkyT*o+B%#col|0k<*9R`ti~;Y0={}9cBZ&} z9BMkxD1k!rSkiTm;0^C7fa^qp;3sIwEaIORnucL3PS4alSmyJcX|>+7mTgly=Rm8y zTjOAzdLp~TwVY46(x)>*7cP3nefPm~^U6!mTLw=e+tjOM>&}}AD0dj5fdC7b)F7Y3 zN=Yi*fK~MBIqh#cRsz^zfuB@rER3c@k7P$uJ+(^C?oRHUI&XisAG!Nd=*lS6yT5_D zIj@Y&ysXR;->a4Y<>smGeZ!!VvrDZWl^HJz;bEIzIXSX9E^kwo8fk~rf1X%&_P}Rr z)d;ya@*!FApdeP;S!;FdV5KCBtpWXlQ4%{gG6+R>$K$?ELvA?TI6rfR!Tru>=}P1t zib5&04m);9?!K})R-gWHlu<-u>eXf39g+`aR#w!$vjS|a^AP2OIxJ7rf6sDm964|` z_4uFP`Ku*B&VOzjZI)9fe8|0}ul$=G=KkCy^PgBORn4CpVSvKXi~NCA z{~SG6_m#6BpI@J|ndwBzKe+iUV@mZ<*7MpS`ZtC`^&cwA>t z1Y!MhD4)b+r0tgewRvg5xyO~qw;E5(>Q7W!qpcg)J)JcVAW?t8i1=Sv;4AV+JT;R~ zW4+YuJpP{7PEJe#b78Km8$z#8;z`*FH^a$>K7o*ak~tZ5r#9zrZU$xK7dFP7X1e>h z`3SH69%gXo{@nWP*B47zegkZO0xW>hUQn`ZP_D7j?p;7Dzr z-<%vIkJhP?vMSiRf`6>7@wmpq#%EJ63n~?~+eb#P*qP7|!0zx0!XyP09}+w0{Dj`Q4Q- zl^+ur{vg;{nsHBVjVk3W2T=8Jh6pQr3%7a2A^TR?Py7=@3omQMF?v%|IPsX1i0eBJ`uY?ibflN$ zTR@R-u`o6NUfJKq^55ol+;XP}Hi~;6AKye`;IzMz?rT%&DYQ#L>G3qxEdKA(asO3z zC~TvrS35?h?cp((>r+paTsYX1tCop1b@};F7nsXC{!>W%-*K@)Pfd4>_^muoKI6rz zFQ3a_=$R`G(*J90?IaVTIQ)g11&%7HLw^m;{834gKk@W`p5Xt7U14L@-_AAbjm-F)5pL$xDNzN+9JH&JvaoFmjWF=uKJeQ#l`$HtO|=;ppd6t5Y`Q zcE)+ryaJPe7x<(VZtf@k5jhdeD*4vuy8{|x3gLsm`|R2JbO33NfLzh&-|m@*?%xU( z8z|^03Y>H=?U7tO-$#(y7@rbQOAdaLVBK0uKg-Wc|6dI@aAzoki_Wkf{NdA)J(z zlPSPoo_wojRgz^pb-1duI&bd`y3e|IXbTSjL!l_A!>efX*7%{PNhS}oGr~W>QzrMh zis|Ywk13Lg!=EQNfTp?pq5$DTa0jYh3i9~WW^-1T!D2g8sT6(l(C@{FDeOay+P z$#J-Pj|LCs3v=f*Qh;of!#ObzaBSSH-+smafrlnmCbu=kFGdI&qR>$^QPyiMH`Iyh zdPOqoW{>A-dVC3Y -5cQSz@D3FydtPx&W)Nfz(Qe;`LXs5L50#$qcQ%!~mIP1N^1x?pr4?^OlEicR zCul3<&e08!e}+ll>f7Jo%=Du4=NE1zSUVg{}=aFUrXE1(9aH72>?*V`zs?ypg$ zfWbFsnf4{{_V}Igjlu_5wKb4X**X>nR4?q`eMK39_#9uSo)7vweO)~T%hsD0bd%Y< zPu552?L>nhin}?zRlXcSW0Q9BnbtBog`G>R$^QG}f49lM4dUOU;lDK$7-;6+xB>jx z`cqeGKS9Q?eP9wm=p{^7LHZ93t?zklr2CTis_K72X+$N!*m&o@M?o zY(*uKm;t2xZds8MNS|zwl(aJ7Rs96L6o=g{ZA(7-_wHl=Zo1!@jf1$r(Jd^By-e?LulU$03y8-*JnQOe8!$>j8|A~Uk`9B!`AR!?+FZ&R! zOhR(z6bZ?1Q@{TPzwtV%3n3x7LL!U4_tZ6JVc0|KgVWLRalatbnWxIs*n85gtu@)9 zWUu?eqpdW{KK^;RCM`*QF{_88Xi#-y9_4wbe@3t9V}^Cn7}+bo{8klBw^b}%7|fZOlIE6{{muF5 z1uj?+iQ_pj6FTGvl4_&B$;gl&zWyO_>*N=he_q1UNl3C^QBWY?ZD|bkknb-tu8@)< zKWLqyzl?kz<7%u%zLTik`~TnK|9LO8f+-GaD5dVM)?QklYRkyVs-URRW|yYV3rM{2 z$UIx6US3dp_hU^-cD=RDIB5v~Dxbge%zt1c@RQLb(=%<1c z{^ze^oqLbdA2}))An)3l%sZ1haJi`|^n>haJ$NsYujt^`>f6Sxt}_XK8u%RTvaMk8 zB@w5&9~L}_BZcqJ8b23f>Y9lUQ}TUTCCE-$K2Qn^Ox+FY|FH8;-@;?{QJG)V zT}%vB&W(V?R$=v}Pd4VO57(76%muO!w}w?S+T<~oVbu;vMfc>_X^7Ws-+wFJ77^|} zx@RGq&aO!axLB4yPzhgDue60F{!IzE5JMn)E8~-Q9^W<{7Q%-!as@vvtX=Jwl|>%I9TK@AZ`h#lxhpaoD|;ML%BW zy`2%HmWIVr=XgE}4D8#wG;4=KiPjs*JKr{$M4Jk?@;_9n*XQkFUoK>v`TMcvbO5&2 zFeaBGQzvuq3jtT!Bk(QjJb!~;WD<^DE_$nR;av7%dnhNzQw$~~rNLCUpFIq#rB6T( zuCvCew=5Kwk&%JJm8LF7ZWs_ARA8|a*1gKvf>$+7bgTGy@MKD|BW8iYzNZcTp|;VE zWkX$zkZkK_F^ox&ZcEPE;(o(ulN(#l6n2E2WV%_y7G6m3Wiqf0J2L=VCCgcG@f8}q z5vD)Rpee2@gna16Q?Rt<%KfF)@rDpqsiPd9!+AcRUAe#i{!Y&7X`uX{b?Zt6TD3&h^?@~FSlDnzi-Xn#au-Ej0X`$v2J ziSzl*zjqt6$SyG^;;qVDmMa(W#9$^-`?U#KawjIk$33b1VTsekv@y6`^GnV)lzW4UTS;9M)Wq~&qQ@J?hE)s;X=wI3pD#Ok`|7u%0;I<~;~}Z3 zI&PC6YinyqkB_#&=ZXZ6;J3`I_ibWQ7ENOrW23k)3UW%L;aq(WUv{L^OQZB74SnEb zBUO#5XCs;*VO3HBmk7%39-8wp5&y6k_2ulTmsVON=;BicHxW|uL zZqU{gQpkNikFPxD7>Kkf=_%bVvO8WhrwaZ2rnu;SZd6>sb3=@CnI7p?hMkH-t76qfjomiTHd+d z3^iqC<#n(RY?V$7Kb#TDoVFxfTYidB zQ$KSaSw~wgErSG;MFR2x1GgyuFG+RmF%R-2TPLa5_q=|F{dSx;!qy!0D<^mh!pR*2 zHr7K|j_mJa58NXKcDQ8d2F(`8A5b=U>%nV2pNH3^9EYEma{Nk)c}msd!#k@?CB1(v z{-AM#u}tkEJ86<18>ueK=H}*^GiSbi`{uR3MH9NVwnj>R0o(Zb-s=tb3n)4&QJb)_g`@^60&zxmdOjjrW>6j{IuLm0UQ_*>mT(Z`}9_Q2;%WRXj4+O;K*qpFK3BwNI<7JIZfR|BgYhnMf>~uU~wz zx3@)1>2rLQ%Tq!Hoasi~;}jhZ$UPBrI+ zfBg7CO+(|~2=S~VPJ*~QIJle^@7>L1W_+--dXDa9IkGDz{BX`{|MYr@QN6%mXdGUI zxUDV^)t@eQ>a_p9X`S@CwLnthI9S#N!>8>Md7hn=bohHXuVx_$6AO!^QS%48@p@({ z?;%40g7J&~EY0nSFvWmI*mv>xm&`;>Sol=yr`y&;UvqPFL)m1U^NWN1gMyg(_0dK~ zll4K2+smWJZNj7FtM!aNyDhrz+e?cd++jtf1@Q_^U>OI6xB&GZf#iB^k$S_wMw@C_ z<8@b3&~IjZHyrFKU^VS7M+dtH2cA}BI~_hp>&dcVgKldywEJj_&gNDmo{NB8Q4V4k6 z%}8;WZqI^xs7F!ia4Op7;P5ahDJe}MmVur=y=T^P^mUV=2HuhYb%q37qe;BimLIG4 zK)IX4Xr-5~_wMAk*W|@%mwkMW6Yl#h4dm5S=B1_@50^TDS>-hu3S6dueCML26%!H? zvgivb(ZtBeijZ&ApRN7#=g&(V3Z6&1)8rSJT)Xm%s>IS1>z@JJ*~t+6%J2ALDMwOMlr`l9Dn6NF4EC)ppc7#y|Fs994s{JNtJJEYJ#sS)G2tpGo)OUfaO4LPUYU**tgfDWE5X= za;l!#&?&2_sVOP_ob25R5#5(>K_%kM)zt~$eAXqC;pghgAz(-y&MIn1Xi$DSc@&s* zc>nU}7#beNV6@Ae7v=aWlAVq=`*m4G?UNPbCHJ=$8Aa_4_c^jdn8j1QzQFEYxP0p` zG#3|_vWiMiPfro!W7YKZ^uzsay3nDaAvzt`gwLPnk;sfe)pn>&o5MQEY5TsL9V4pgK!IaZq)*bY%LIAuLkptS}L|jxKTFctG+@e z`{N-}=HiJm!Azgx;wmA~f=ABGbR{h^CFbU?%;!|;lse8jbVwB2j7nDM95=FsY|Qq^ zV0tkbswrt{^P79Et*sEqp{5UkItomeQP`R~)Sw}l_gU^|*wdVT4h{|ra(NDR_R^A) zqBP6s%*;$Uzsi;G=Y)qH!xYk5+Sq=_+ZGhZ{ZMuqdcAo8+T~{IOl8F}I$-O1#mp z<xP7=i+E82TdAQj>>bV|-E#K&ty?fsvt{~h>EDm;ab>D@J`L65A zWQ4A@52e)cfy49X30MkNNiAXq4+>m~;_O*b*Of77w;&s4)U81}8VrBy;qJaQ-#^lZ z0xMo37Q-fcz?-+nh#F{?XzS=?Zypd#;wL93&4M)K%*@Q3oHpTgg?4b6#0Az`I^O-E z5(j*AQevW|&nIYD6k|lLqF$3zUO0QUi=m>t{I}nJ8$67KyyEzA&4I3J`qfiR?ZR|# z=+4}93O2GOBa)mT9(P(MczgT%bvNSh642Sf zL9&O8H^k<6c{K4nyu6Ez zp=?mO!s8fV5XhA%6!_wOUy8h{bqGU{tDvqVZgZnFOnJDudxR==E^69b*kj6Kyz82a zcXEb^1MLOu32dK5UuIKB2VE%SIXDSjmtiLq_;bGf~A>wQk?OU33jGRV(ny*P~Y;!;Zh%UT*CPz)rBF z&sT>Hs@&ffU7xH5Fs}4$0ioP=_1DbI4AcOWEO&PxPWQd)`@pI4;N9h`s2bn%J*sG_ z_14?&6-Qx;lJwwJg8f=5%F1gH;zyw@s5)G4Ak8>bLD#Nb8}eLl3z6806l$`J78?O$cysm=l=U0#hmbD; zCLpRfXHZL*K%D^@2yOW7)fqTNdI7`6MCrhrg*nizjoFu8O@2*jelC(mTD_{6jo$Te zL`+%<^>?lRxrDbA6poi5NDiXEv^n)_7u){)4vlM9Pmjt;==R!k+^1{3z$)ok|Bn9X z=!k}f2C$@92&94*s^WeY1WmQTfPlSu-D5GgHABt7t(%D@4$}a9VILkJ9frMsZz&88 z+z~IO>p|6(ve%pAEojtCO{ESQF;zYqGFW$aH{@e(ZtnH9H7Gq)m6h$Gem5nzc5`=c zkK|_)6;;=y&YB%AD^^IeP$bY@q@~@OmO6G@7|0vUfqbW3XsQI+hg|XkoV&rH`!fy} zRcfkX#k3zAHe7t(1+nnWM=T{^##^GbX}vlC&q+U%4*o{;!RPj1Fc>qU%<#|<6yL*Z z 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 z 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 = []; hasSched: number | undefined; pid: number | undefined; processName: string | undefined; diff --git a/ide/src/trace/component/SpHelp.ts b/ide/src/trace/component/SpHelp.ts index 63c247435..4af9598ea 100644 --- a/ide/src/trace/component/SpHelp.ts +++ b/ide/src/trace/component/SpHelp.ts @@ -150,19 +150,6 @@ export class SpHelp extends BaseElement { `/application/doc/quickstart_page_fault.html?${that.dark} width="100%" height="100%">

    `; }, }, - { - title: '进程smaps抓取和展示说明', - icon: '', - clickHandler: function (item: MenuItem) { - SpStatisticsHttpUtil.addOrdinaryVisitAction({ - event: 'smaps', - action: 'help_doc', - }); - that.appContent!.innerHTML = - ' 展示快捷方式 + + +
    v
    + + 展示/隐藏Vsync信号 + diff --git a/ide/src/trace/component/SpSystemTrace.ts b/ide/src/trace/component/SpSystemTrace.ts index 99cbb8e29..738015b54 100644 --- a/ide/src/trace/component/SpSystemTrace.ts +++ b/ide/src/trace/component/SpSystemTrace.ts @@ -84,6 +84,7 @@ import { TabPaneCurrentSelection } from './trace/sheet/TabPaneCurrentSelection'; import { SpChartList } from './trace/SpChartList'; import './trace/SpChartList'; import { AppStartupStruct } from '../database/ui-worker/ProcedureWorkerAppStartup'; +import { AllAppStartupStruct } from '../database/ui-worker/ProcedureWorkerAllAppStartup'; import { SoStruct } from '../database/ui-worker/ProcedureWorkerSoInit'; import { TabPaneTaskFrames } from './trace/sheet/task/TabPaneTaskFrames'; import { FlagsConfig } from './SpFlags'; @@ -264,6 +265,8 @@ export class SpSystemTrace extends BaseElement { } startPoint.y = startPoint.rowEL!.translateY! + startPoint.offsetY; endPoint.y = endPoint.rowEL!.translateY! + endPoint.offsetY; + startPoint.backrowEL = startPoint.rowEL; + endPoint.backrowEL = endPoint.rowEL; this.linkNodes.push([startPoint, endPoint]); } @@ -1395,11 +1398,11 @@ export class SpSystemTrace extends BaseElement { let tr = it.target as TraceRow; if (!it.isIntersecting) { tr.sleeping = true; - this.invisibleRows.push(tr); + this.invisibleRows.indexOf(tr) == -1 && this.invisibleRows.push(tr); this.visibleRows = this.visibleRows.filter((it) => !it.sleeping); } else { tr.sleeping = false; - this.visibleRows.push(tr); + this.visibleRows.indexOf(tr) == -1 && this.visibleRows.push(tr); this.invisibleRows = this.invisibleRows.filter((it) => it.sleeping); } this.visibleRows @@ -2543,7 +2546,7 @@ export class SpSystemTrace extends BaseElement { if (!SportRuler.isMouseInSportRuler) { this.traceSheetEL?.setAttribute('mode', 'hidden'); } - this.removeLinkLinesByBusinessType('task'); + this.removeLinkLinesByBusinessType('task','thread'); this.refreshCanvas(true); JankStruct.delJankLineFlag = true; } @@ -2579,6 +2582,10 @@ export class SpSystemTrace extends BaseElement { TraceRow.ROW_TYPE_APP_STARTUP, () => AppStartupStruct.hoverStartupStruct !== null && AppStartupStruct.hoverStartupStruct !== undefined, ], + [ + TraceRow.ROW_TYPE_ALL_APPSTARTUPS, + () => AllAppStartupStruct.hoverStartupStruct !== null && AllAppStartupStruct.hoverStartupStruct !== undefined, + ], [TraceRow.ROW_TYPE_STATIC_INIT, () => SoStruct.hoverSoStruct !== null && SoStruct.hoverSoStruct !== undefined], [TraceRow.ROW_TYPE_JANK, () => JankStruct.hoverJankStruct !== null && JankStruct.hoverJankStruct !== undefined], [TraceRow.ROW_TYPE_HEAP, () => HeapStruct.hoverHeapStruct !== null && HeapStruct.hoverHeapStruct !== undefined], @@ -2744,6 +2751,7 @@ export class SpSystemTrace extends BaseElement { this.traceSheetEL?.displayCpuData( CpuStruct.selectCpuStruct!, (wakeUpBean) => { + this.removeLinkLinesByBusinessType('thread'); CpuStruct.wakeupBean = wakeUpBean; this.refreshCanvas(true); }, @@ -2832,6 +2840,7 @@ export class SpSystemTrace extends BaseElement { ); } this.hoverStructNull(); + let flag = JSON.parse(JSON.stringify(ThreadStruct.selectThreadStruct)); this.selectStructNull(); this.wakeupListNull(); ThreadStruct.hoverThreadStruct = findEntry; @@ -2842,7 +2851,16 @@ export class SpSystemTrace extends BaseElement { threadClickHandler, cpuClickHandler, threadClickPreviousHandler, - threadClickNextHandler + threadClickNextHandler, + (datas) => { + this.removeLinkLinesByBusinessType('thread'); + datas.forEach((data) => { + let endParentRow = this.shadowRoot?.querySelector>( + `trace-row[row-id='${data.pid}'][folder]` + ); + this.drawThreadLine(endParentRow, flag, data); + }); + } ); this.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true); } @@ -2959,6 +2977,7 @@ export class SpSystemTrace extends BaseElement { ); this.timerShaftEL?.modifyFlagList(undefined); } else if (clickRowType === TraceRow.ROW_TYPE_THREAD && ThreadStruct.hoverThreadStruct) { + this.removeLinkLinesByBusinessType('thread'); ThreadStruct.selectThreadStruct = ThreadStruct.hoverThreadStruct; this.timerShaftEL?.drawTriangle(ThreadStruct.selectThreadStruct!.startTime || 0, 'inverted'); this.traceSheetEL?.displayThreadData( @@ -3142,6 +3161,10 @@ export class SpSystemTrace extends BaseElement { AppStartupStruct.selectStartupStruct = AppStartupStruct.hoverStartupStruct; this.traceSheetEL?.displayStartupData(AppStartupStruct.selectStartupStruct, scrollToFuncHandler); this.timerShaftEL?.modifyFlagList(undefined); + } else if(clickRowType === TraceRow.ROW_TYPE_ALL_APPSTARTUPS && AllAppStartupStruct.hoverStartupStruct){ + AllAppStartupStruct.selectStartupStruct = AllAppStartupStruct.hoverStartupStruct; + this.traceSheetEL?.displayAllStartupData(AllAppStartupStruct.selectStartupStruct!, scrollToFuncHandler) + this.timerShaftEL?.modifyFlagList(undefined); } else if (clickRowType === TraceRow.ROW_TYPE_STATIC_INIT && SoStruct.hoverSoStruct) { SoStruct.selectSoStruct = SoStruct.hoverSoStruct; this.traceSheetEL?.displayStaticInitData(SoStruct.selectSoStruct, scrollToFuncHandler); @@ -3234,6 +3257,9 @@ export class SpSystemTrace extends BaseElement { if (!JankStruct.selectJankStruct) { this.removeLinkLinesByBusinessType('janks'); } + if (!ThreadStruct.selectThreadStruct) { + this.removeLinkLinesByBusinessType('thread'); + } if (row) { let pointEvent = this.createPointEvent(row); SpStatisticsHttpUtil.addOrdinaryVisitAction({ @@ -3677,6 +3703,110 @@ export class SpSystemTrace extends BaseElement { } } + drawThreadLine(endParentRow: any, selectThreadStruct: ThreadStruct, data: any) { + let collectList = this.favoriteChartListEL!.getCollectRows(); + let startRow: any; + if (selectThreadStruct == undefined || selectThreadStruct == null) { + return; + } + let selectRowId = selectThreadStruct?.tid; + startRow = this.shadowRoot?.querySelector>( + `trace-row[row-id='${selectRowId}'][row-type='thread']` + ); + if (!startRow) { + for (let index = 0; index < collectList.length; index++) { + let collectChart = collectList[index]; + if (collectChart.rowId === selectRowId?.toString() && collectChart.rowType === 'thread') { + startRow = collectChart; + break; + } + } + } + function collectionHasThread(threadRow: any): boolean { + for (let item of collectList!) { + if (item.rowId === threadRow.rowId && item.rowType === threadRow.rowType) { + return false; + } + } + return true; + } + + if (endParentRow) { + //终点的父泳道过滤出选中的Struct + let endRowStruct: any; + //泳道展开的情况,查找endRowStruct + endRowStruct = this.shadowRoot?.querySelector>( + `trace-row[row-id='${data.tid}'][row-type='thread']` + ); + //泳道未展开的情况,查找endRowStruct + if (!endRowStruct) { + endRowStruct = endParentRow.childrenList.find((item: TraceRow) => { + return item.rowId === `${data.tid}` && item.rowType === 'thread' + }); + } + if (endRowStruct) { + let findJankEntry = endRowStruct!.dataList!.find((dat: any) => dat.startTime == data.startTime && dat.dur! > 0); + //连线规则 + let ts: number = 0; + if (findJankEntry) { + ts = selectThreadStruct.startTime! + selectThreadStruct.dur! / 2; + let startParentRow: any; + // startRow为子泳道,子泳道不存在,使用父泳道 + if (startRow) { + startParentRow = this.shadowRoot?.querySelector>( + `trace-row[row-id='${startRow.rowParentId}'][folder]` + ); + } else { + startRow = this.shadowRoot?.querySelector>( + `trace-row[row-id='${selectThreadStruct?.pid}'][folder]` + ); + } + let endY = endRowStruct!.translateY!; + let endRowEl = endRowStruct; + let endOffSetY = 20 * 0.5; + let expansionFlag = collectionHasThread(endRowStruct); + if (!endParentRow.expansion && expansionFlag) { + endY = endParentRow!.translateY!; + endRowEl = endParentRow; + endOffSetY = 10 * 0.5; + } + let startY = startRow!.translateY!; + let startRowEl = startRow; + let startOffSetY = 20 * 0.5; + expansionFlag = collectionHasThread(startRow); + if (startParentRow && !startParentRow.expansion && expansionFlag) { + startY = startParentRow!.translateY!; + startRowEl = startParentRow; + startOffSetY = 10 * 0.5; + } + this.addPointPair( + this.makePoint( + ns2xByTimeShaft(ts, this.timerShaftEL!), + ts, + startY, + startRowEl!, + startOffSetY, + 'thread', + LineType.StraightLine, + selectThreadStruct.startTime == ts, + ), + this.makePoint( + ns2xByTimeShaft(findJankEntry.startTime!, this.timerShaftEL!), + findJankEntry.startTime!, + endY, + endRowEl, + endOffSetY, + 'thread', + LineType.StraightLine, + true, + ) + ); + this.refreshCanvas(true); + } + } + } + } + translateByMouseMove(ev: MouseEvent): void { ev.preventDefault(); let offset = 0; @@ -4465,6 +4595,12 @@ export class SpSystemTrace extends BaseElement { if (it.folder) { let offsetYTimeOut: any = undefined; it.addEventListener('expansion-change', (event: any) => { + let max = [...this.rowsPaneEL!.querySelectorAll('trace-row')].reduce( + (pre, cur) => pre + cur.clientHeight!, + 0 + ); + let offset = this.rowsPaneEL!.scrollHeight - max; + this.rowsPaneEL!.scrollTop = this.rowsPaneEL!.scrollTop - offset; JankStruct.delJankLineFlag = false; if (offsetYTimeOut) { clearTimeout(offsetYTimeOut); diff --git a/ide/src/trace/component/chart/SpAllAppStartups.ts b/ide/src/trace/component/chart/SpAllAppStartups.ts new file mode 100644 index 000000000..cded62c6a --- /dev/null +++ b/ide/src/trace/component/chart/SpAllAppStartups.ts @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SpSystemTrace } from '../SpSystemTrace'; +import { TraceRow } from '../trace/base/TraceRow'; +import { renders } from '../../database/ui-worker/ProcedureWorker'; +import { CpuFreqStruct } from '../../database/ui-worker/ProcedureWorkerFreq'; +import { + queryAppStartupProcessIds, + queryProcessStartup, + querySingleAppStartupsName, +} from '../../database/SqlLite'; +import { FlagsConfig } from '../SpFlags'; +import { AllAppStartupStruct, AllAppStartupRender } from '../../database/ui-worker/ProcedureWorkerAllAppStartup'; + +export class SpAllAppStartupsChart { + private readonly trace: SpSystemTrace | undefined; + static APP_STARTUP_PID_ARR: Array = []; + static jsonRow: TraceRow | undefined; + static trace: SpSystemTrace; + static AllAppStartupsNameArr: any[] = []; + static allAppStartupsAva: number[] = []; + + constructor(trace: SpSystemTrace) { + SpAllAppStartupsChart.trace = trace; + } + + + + + + async init() { + SpAllAppStartupsChart.APP_STARTUP_PID_ARR = []; + let appStartUpPids = await queryAppStartupProcessIds(); + appStartUpPids.forEach((it) => SpAllAppStartupsChart.APP_STARTUP_PID_ARR.push(it.pid)); + SpAllAppStartupsChart.AllAppStartupsNameArr = []; + SpAllAppStartupsChart.allAppStartupsAva = []; + for (let i = 0; i < SpAllAppStartupsChart.APP_STARTUP_PID_ARR.length; i++) { + let tmpSingleApp: any[] = await queryProcessStartup(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]!); + if (tmpSingleApp.length == 8) { + let avilSingleName = await querySingleAppStartupsName(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]!); + SpAllAppStartupsChart.allAppStartupsAva.push(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]); + SpAllAppStartupsChart.AllAppStartupsNameArr.push(avilSingleName![0].name); + } + } + let loadAppStartup: boolean = FlagsConfig.getFlagsConfigEnableStatus('AppStartup'); + if (loadAppStartup && SpAllAppStartupsChart.allAppStartupsAva.length) await this.initFolder(); + } + + async initFolder() { + let row: TraceRow = TraceRow.skeleton(); + row.setAttribute('hasStartup', 'true'); + row.rowId = `all-app-start-${SpAllAppStartupsChart.APP_STARTUP_PID_ARR![0]}`; + row.index = 0; + row.rowType = TraceRow.ROW_TYPE_ALL_APPSTARTUPS; + row.rowParentId = ''; + row.folder = false; + row.style.height = '40px'; + row.name = `All App Startups`; + row.selectChangeHandler = SpAllAppStartupsChart.trace.selectChangeHandler; + row.favoriteChangeHandler = SpAllAppStartupsChart.trace.favoriteChangeHandler; + row.supplier = async (): Promise> => { + let sendRes: AllAppStartupStruct[] | PromiseLike = []; + for (let i = 0; i < SpAllAppStartupsChart.allAppStartupsAva.length; i++) { + let tmpResArr = await queryProcessStartup(SpAllAppStartupsChart.allAppStartupsAva[i]); + let maxStartTs: number | undefined = tmpResArr[0].startTs; + let minStartTs: number | undefined = tmpResArr[0].startTs; + let singleDur = tmpResArr[0].dur; + let endTs: number | undefined = tmpResArr[0].startTs; + if (tmpResArr.length > 1) { + for (let j = 0; j < tmpResArr.length; j++) { + if (Number(tmpResArr[j].startTs) > Number(maxStartTs)) { + maxStartTs = tmpResArr[j].startTs; + } else if (Number(tmpResArr[j].startTs) < Number(minStartTs)) { + minStartTs = tmpResArr[j].startTs; + } + } + tmpResArr.forEach((item) => { + if (item.startTs == maxStartTs) { + endTs = Number(item.startTs) + Number(item.dur); + singleDur = Number(endTs) - Number(minStartTs); + } + }) + } else if (tmpResArr.length === 1) { + minStartTs = tmpResArr[0].startTs; + singleDur = tmpResArr[0].dur; + } + sendRes.push( + { + dur: singleDur, + value: undefined, + startTs: minStartTs, + pid: SpAllAppStartupsChart.allAppStartupsAva[i], + process: undefined, + itid: undefined, + endItid: undefined, + tid: SpAllAppStartupsChart.allAppStartupsAva[i], + startName: undefined, + stepName: SpAllAppStartupsChart.AllAppStartupsNameArr[i], + translateY: undefined, + frame: undefined, + isHover: false + } + ) + } + return sendRes + } + + row.onThreadHandler = (useCache): void => { + let context: CanvasRenderingContext2D; + if (row.currentContext) { + context = row.currentContext; + } else { + context = row.collect ? SpAllAppStartupsChart.trace.canvasFavoritePanelCtx! : SpAllAppStartupsChart.trace.canvasPanelCtx!; + } + row.canvasSave(context); + (renders['all-app-start-up'] as AllAppStartupRender).renderMainThread( + { + appStartupContext: context, + useCache: useCache, + type: `app-startup ${row.rowId}`, + }, + row + ); + row.canvasRestore(context); + }; + SpAllAppStartupsChart.trace.rowsEL?.appendChild(row); + } +} \ No newline at end of file diff --git a/ide/src/trace/component/chart/SpChartManager.ts b/ide/src/trace/component/chart/SpChartManager.ts index fc9b1fc2a..248f13166 100644 --- a/ide/src/trace/component/chart/SpChartManager.ts +++ b/ide/src/trace/component/chart/SpChartManager.ts @@ -49,6 +49,7 @@ import { MemoryConfig } from '../../bean/MemoryConfig'; import { FlagsConfig } from '../SpFlags'; import { SpLogChart } from './SpLogChart'; import { SpHiSysEventChart } from './SpHiSysEventChart'; +import { SpAllAppStartupsChart } from './SpAllAppStartups'; import {setVSyncData} from './VSync'; export class SpChartManager { @@ -69,6 +70,7 @@ export class SpChartManager { private smapsChart: VmTrackerChart; private clockChart: SpClockChart; private irqChart: SpIrqChart; + private spAllAppStartupsChart!: SpAllAppStartupsChart; frameTimeChart: SpFrameTimeChart; public arkTsChart: SpArkTsChart; private logChart: SpLogChart; @@ -94,6 +96,7 @@ export class SpChartManager { this.arkTsChart = new SpArkTsChart(trace); this.logChart = new SpLogChart(trace); this.spHiSysEvent = new SpHiSysEventChart(trace); + this.spAllAppStartupsChart = new SpAllAppStartupsChart(trace); } async init(progress: Function) { @@ -165,6 +168,7 @@ export class SpChartManager { await this.arkTsChart.initFolder(); info('ark ts initialized'); await this.frameTimeChart.init(); + await this.spAllAppStartupsChart.init(); progress('process', 92); await this.process.initAsyncFuncData(); await this.process.initDeliverInputEvent(); diff --git a/ide/src/trace/component/chart/SpProcessChart.ts b/ide/src/trace/component/chart/SpProcessChart.ts index 830e46b37..90d940b0c 100644 --- a/ide/src/trace/component/chart/SpProcessChart.ts +++ b/ide/src/trace/component/chart/SpProcessChart.ts @@ -431,75 +431,146 @@ export class SpProcessChart { if (offsetYTimeOut) { clearTimeout(offsetYTimeOut); } - if (e.detail.expansion) { - offsetYTimeOut = setTimeout(() => { - this.trace.linkNodes.forEach((linkNodeItem) => { - JankStruct.selectJankStructList?.forEach((selectProcessStruct: any) => { - if (e.detail.rowId == selectProcessStruct.pid) { - JankStruct.selectJankStruct = selectProcessStruct; - JankStruct.hoverJankStruct = selectProcessStruct; + if (JankStruct.selectJankStruct !== null && JankStruct.selectJankStruct !== undefined) { + if (e.detail.expansion) { + offsetYTimeOut = setTimeout(() => { + this.trace.linkNodes.forEach((linkNodeItem) => { + JankStruct.selectJankStructList?.forEach((selectProcessStruct: any) => { + if (e.detail.rowId == selectProcessStruct.pid) { + JankStruct.selectJankStruct = selectProcessStruct; + JankStruct.hoverJankStruct = selectProcessStruct; + } + }); + if (linkNodeItem[0].rowEL.collect) { + linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.getBoundingClientRect().top - 195; + } else { + linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } + linkNodeItem[0].y = linkNodeItem[0].rowEL!.translateY! + linkNodeItem[0].offsetY; + if (linkNodeItem[1].rowEL.collect) { + linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.getBoundingClientRect().top - 195; + } else { + linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } + linkNodeItem[1].y = linkNodeItem[1].rowEL!.translateY! + linkNodeItem[1].offsetY; + if (actualRow) { + if (linkNodeItem[0].rowEL.rowId == e.detail.rowId) { + linkNodeItem[0].x = ns2xByTimeShaft(linkNodeItem[0].ns, this.trace.timerShaftEL!); + linkNodeItem[0].y = actualRow!.translateY! + linkNodeItem[0].offsetY * 2; + linkNodeItem[0].offsetY = linkNodeItem[0].offsetY * 2; + linkNodeItem[0].rowEL = actualRow!; + } else if (linkNodeItem[1].rowEL.rowId == e.detail.rowId) { + linkNodeItem[1].x = ns2xByTimeShaft(linkNodeItem[1].ns, this.trace.timerShaftEL!); + linkNodeItem[1].y = actualRow!.translateY! + linkNodeItem[1].offsetY * 2; + linkNodeItem[1].offsetY = linkNodeItem[1].offsetY * 2; + linkNodeItem[1].rowEL = actualRow!; + } } }); - if (linkNodeItem[0].rowEL.collect) { - linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.getBoundingClientRect().top - 195; - } else { - linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } - linkNodeItem[0].y = linkNodeItem[0].rowEL!.translateY! + linkNodeItem[0].offsetY; - if (linkNodeItem[1].rowEL.collect) { - linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.getBoundingClientRect().top - 195; - } else { - linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } - linkNodeItem[1].y = linkNodeItem[1].rowEL!.translateY! + linkNodeItem[1].offsetY; - if (actualRow) { - if (linkNodeItem[0].rowEL.rowId == e.detail.rowId) { + }, 300); + } else { + if (JankStruct!.selectJankStruct) { + JankStruct.selectJankStructList?.push(JankStruct!.selectJankStruct); + } + offsetYTimeOut = setTimeout(() => { + this.trace.linkNodes?.forEach((linkProcessItem) => { + if (linkProcessItem[0].rowEL.collect) { + linkProcessItem[0].rowEL.translateY = linkProcessItem[0].rowEL.getBoundingClientRect().top - 195; + } else { + linkProcessItem[0].rowEL.translateY = + linkProcessItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } + linkProcessItem[0].y = linkProcessItem[0].rowEL!.translateY! + linkProcessItem[0].offsetY; + if (linkProcessItem[1].rowEL.collect) { + linkProcessItem[1].rowEL.translateY = linkProcessItem[1].rowEL.getBoundingClientRect().top - 195; + } else { + linkProcessItem[1].rowEL.translateY = + linkProcessItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } + linkProcessItem[1].y = linkProcessItem[1].rowEL!.translateY! + linkProcessItem[1].offsetY; + if (linkProcessItem[0].rowEL.rowParentId == e.detail.rowId) { + linkProcessItem[0].x = ns2xByTimeShaft(linkProcessItem[0].ns, this.trace.timerShaftEL!); + linkProcessItem[0].y = processRow!.translateY! + linkProcessItem[0].offsetY / 2; + linkProcessItem[0].offsetY = linkProcessItem[0].offsetY / 2; + linkProcessItem[0].rowEL = processRow!; + } else if (linkProcessItem[1].rowEL.rowParentId == e.detail.rowId) { + linkProcessItem[1].x = ns2xByTimeShaft(linkProcessItem[1].ns, this.trace.timerShaftEL!); + linkProcessItem[1].y = processRow!.translateY! + linkProcessItem[1].offsetY / 2; + linkProcessItem[1].offsetY = linkProcessItem[1].offsetY / 2; + linkProcessItem[1].rowEL = processRow!; + } + }); + }, 300); + } + } else { + if (e.detail.expansion) { + offsetYTimeOut = setTimeout(() => { + this.trace.linkNodes.forEach((linkNodeItem) => { + ThreadStruct.selectThreadStructList?.forEach((selectProcessStruct: any) => { + if (e.detail.rowId == selectProcessStruct.pid) { + ThreadStruct.selectThreadStruct = selectProcessStruct; + ThreadStruct.hoverThreadStruct = selectProcessStruct; + } + }); + if (linkNodeItem[0].rowEL.expansion && linkNodeItem[0].backrowEL) { + linkNodeItem[0].rowEL = linkNodeItem[0].backrowEL; + if (linkNodeItem[0].rowEL.collect) { + linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.getBoundingClientRect().top - 195; + } else { + linkNodeItem[0].rowEL.translateY = linkNodeItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } linkNodeItem[0].x = ns2xByTimeShaft(linkNodeItem[0].ns, this.trace.timerShaftEL!); - linkNodeItem[0].y = actualRow!.translateY! + linkNodeItem[0].offsetY * 2; linkNodeItem[0].offsetY = linkNodeItem[0].offsetY * 2; - linkNodeItem[0].rowEL = actualRow!; - } else if (linkNodeItem[1].rowEL.rowId == e.detail.rowId) { + linkNodeItem[0].y = linkNodeItem[0].rowEL.translateY + linkNodeItem[0].offsetY; + } + if (linkNodeItem[1].rowEL.expansion && linkNodeItem[1].backrowEL) { + linkNodeItem[1].rowEL = linkNodeItem[1].backrowEL; + if (linkNodeItem[1].rowEL.collect) { + linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.getBoundingClientRect().top - 195; + } else { + linkNodeItem[1].rowEL.translateY = linkNodeItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } linkNodeItem[1].x = ns2xByTimeShaft(linkNodeItem[1].ns, this.trace.timerShaftEL!); - linkNodeItem[1].y = actualRow!.translateY! + linkNodeItem[1].offsetY * 2; linkNodeItem[1].offsetY = linkNodeItem[1].offsetY * 2; - linkNodeItem[1].rowEL = actualRow!; + linkNodeItem[1].y = linkNodeItem[1].rowEL!.translateY! + linkNodeItem[1].offsetY; } - } - }); - }, 300); - } else { - if (JankStruct!.selectJankStruct) { - JankStruct.selectJankStructList?.push(JankStruct!.selectJankStruct); + }); + }, 300); + } else { + if (ThreadStruct!.selectThreadStruct) { + ThreadStruct.selectThreadStructList?.push(ThreadStruct!.selectThreadStruct); + } + offsetYTimeOut = setTimeout(() => { + this.trace.linkNodes?.forEach((linkProcessItem) => { + if (linkProcessItem[0].rowEL.collect) { + linkProcessItem[0].rowEL.translateY = linkProcessItem[0].rowEL.getBoundingClientRect().top - 195; + } else { + linkProcessItem[0].rowEL.translateY = + linkProcessItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } + linkProcessItem[0].y = processRow!.translateY + linkProcessItem[0].offsetY;//11 + if (linkProcessItem[1].rowEL.collect) { + linkProcessItem[1].rowEL.translateY = linkProcessItem[1].rowEL.getBoundingClientRect().top - 195; + } else { + linkProcessItem[1].rowEL.translateY = + linkProcessItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; + } + linkProcessItem[1].y = linkProcessItem[1].rowEL!.translateY + linkProcessItem[1].offsetY; + if (linkProcessItem[0].rowEL.rowParentId == e.detail.rowId) { + linkProcessItem[0].x = ns2xByTimeShaft(linkProcessItem[0].ns, this.trace.timerShaftEL!); + linkProcessItem[0].y = processRow!.translateY! + linkProcessItem[0].offsetY / 2; + linkProcessItem[0].offsetY = linkProcessItem[0].offsetY / 2; + linkProcessItem[0].rowEL = processRow!; + } + if (linkProcessItem[1].rowEL.rowParentId == e.detail.rowId) { + linkProcessItem[1].x = ns2xByTimeShaft(linkProcessItem[1].ns, this.trace.timerShaftEL!); + linkProcessItem[1].y = processRow!.translateY! + linkProcessItem[1].offsetY / 2; + linkProcessItem[1].offsetY = linkProcessItem[1].offsetY / 2; + linkProcessItem[1].rowEL = processRow!; + } + }); + }, 300); } - offsetYTimeOut = setTimeout(() => { - this.trace.linkNodes?.forEach((linkProcessItem) => { - if (linkProcessItem[0].rowEL.collect) { - linkProcessItem[0].rowEL.translateY = linkProcessItem[0].rowEL.getBoundingClientRect().top - 195; - } else { - linkProcessItem[0].rowEL.translateY = - linkProcessItem[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } - linkProcessItem[0].y = linkProcessItem[0].rowEL!.translateY! + linkProcessItem[0].offsetY; - if (linkProcessItem[1].rowEL.collect) { - linkProcessItem[1].rowEL.translateY = linkProcessItem[1].rowEL.getBoundingClientRect().top - 195; - } else { - linkProcessItem[1].rowEL.translateY = - linkProcessItem[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop; - } - linkProcessItem[1].y = linkProcessItem[1].rowEL!.translateY! + linkProcessItem[1].offsetY; - if (linkProcessItem[0].rowEL.rowParentId == e.detail.rowId) { - linkProcessItem[0].x = ns2xByTimeShaft(linkProcessItem[0].ns, this.trace.timerShaftEL!); - linkProcessItem[0].y = processRow!.translateY! + linkProcessItem[0].offsetY / 2; - linkProcessItem[0].offsetY = linkProcessItem[0].offsetY / 2; - linkProcessItem[0].rowEL = processRow!; - } else if (linkProcessItem[1].rowEL.rowParentId == e.detail.rowId) { - linkProcessItem[1].x = ns2xByTimeShaft(linkProcessItem[1].ns, this.trace.timerShaftEL!); - linkProcessItem[1].y = processRow!.translateY! + linkProcessItem[1].offsetY / 2; - linkProcessItem[1].offsetY = linkProcessItem[1].offsetY / 2; - linkProcessItem[1].rowEL = processRow!; - } - }); - }, 300); } let refreshTimeOut = setTimeout(() => { this.trace.refreshCanvas(true); diff --git a/ide/src/trace/component/trace/base/RangeSelect.ts b/ide/src/trace/component/trace/base/RangeSelect.ts index a224e5967..5e3c8c43a 100644 --- a/ide/src/trace/component/trace/base/RangeSelect.ts +++ b/ide/src/trace/component/trace/base/RangeSelect.ts @@ -87,7 +87,11 @@ export class RangeSelect { row.docompositionList = []; }); docompositionData = []; - if (this.rangeTraceRow.length === 1 && this.rangeTraceRow[0]?.getAttribute('row-type') === 'func') { + if ( + this.rangeTraceRow.length === 1 && + this.rangeTraceRow[0]?.getAttribute('row-type') === 'func' && + this.rangeTraceRow[0]?.getAttribute('name')?.startsWith('render_service') + ) { querySearchRowFuncData( 'H:RSMainThread::DoComposition', Number(this.rangeTraceRow[0]?.getAttribute('row-id')), diff --git a/ide/src/trace/component/trace/base/TraceRow.ts b/ide/src/trace/component/trace/base/TraceRow.ts index 097d62414..55a759360 100644 --- a/ide/src/trace/component/trace/base/TraceRow.ts +++ b/ide/src/trace/component/trace/base/TraceRow.ts @@ -117,6 +117,7 @@ export class TraceRow extends HTMLElement { static ROW_TYPE_PURGEABLE_TOTAL_VM = 'purgeable-total-vm'; static ROW_TYPE_PURGEABLE_PIN_VM = 'purgeable-pin-vm'; static ROW_TYPE_LOGS = 'logs'; + static ROW_TYPE_ALL_APPSTARTUPS = 'all-appstartups' static FRAME_WIDTH: number = 0; static range: TimeRange | undefined | null; static rangeSelectObject: RangeSelectStruct | undefined; diff --git a/ide/src/trace/component/trace/base/TraceSheet.ts b/ide/src/trace/component/trace/base/TraceSheet.ts index ad04d93ed..6993bcd00 100644 --- a/ide/src/trace/component/trace/base/TraceSheet.ts +++ b/ide/src/trace/component/trace/base/TraceSheet.ts @@ -42,6 +42,7 @@ import { type TabPaneNMStatisticAnalysis } from '../sheet/native-memory/TabPaneN import { type TabPaneCurrent } from '../sheet/TabPaneCurrent'; import { type SlicesTime } from '../timer-shaft/SportRuler'; import { type AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAppStartup'; +import { type AllAppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAllAppStartup'; import { type SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit'; import { type FrameAnimationStruct } from '../../../database/ui-worker/ProcedureWorkerFrameAnimation'; import { type TraceRow } from './TraceRow'; @@ -155,7 +156,7 @@ export class TraceSheet extends BaseElement { const select = this.processTree!.getCheckdKeys(); const selectIPid = Number(select[0]); this.switchDiv!.visible = 'false'; - this.updateRangeSelect(selectIPid) + this.updateRangeSelect(selectIPid); this.lastSelectIPid = selectIPid; }; @@ -481,14 +482,16 @@ export class TraceSheet extends BaseElement { scrollCallback: ((e: ThreadStruct) => void) | undefined, scrollWakeUp: (d: any) => void | undefined, scrollPreviousData: (d: ThreadStruct) => void, - scrollNextData: (d: ThreadStruct) => void + scrollNextData: (d: ThreadStruct) => void, + callback: ((data: Array) => void) | undefined = undefined ) => this.displayTab('current-selection').setThreadData( data, scrollCallback, scrollWakeUp, scrollPreviousData, - scrollNextData + scrollNextData, + callback ); displayMemData = (data: ProcessMemStruct): void => this.displayTab('current-selection').setMemData(data); @@ -498,6 +501,8 @@ export class TraceSheet extends BaseElement { this.displayTab('current-selection').setIrqData(data); displayStartupData = (data: AppStartupStruct, scrollCallback: Function): void => this.displayTab('current-selection').setStartupData(data, scrollCallback); + displayAllStartupData = (data: AllAppStartupStruct, scrollCallback: Function): void => + this.displayTab('current-selection').setAllStartupData(data, scrollCallback); displayStaticInitData = (data: SoStruct, scrollCallback: Function): void => this.displayTab('current-selection').setStaticInitData(data, scrollCallback); @@ -802,9 +807,9 @@ export class TraceSheet extends BaseElement { if (selection && selection.nativeMemoryAllProcess.length > 1) { this.switchDiv!.style.display = 'flex'; if (this.isProcessEqual(selection.nativeMemoryAllProcess)) { - if (this.processTree){ - for (const data of this.processTree.treeData){ - if (data.key === `${selection.nativeMemoryCurrentIPid}`){ + if (this.processTree) { + for (const data of this.processTree.treeData) { + if (data.key === `${selection.nativeMemoryCurrentIPid}`) { data.checked = true; } else { data.checked = false; @@ -841,7 +846,7 @@ export class TraceSheet extends BaseElement { let component: any = this.shadowRoot ?.querySelector(`#tabs lit-tabpane[key='${key}']`) ?.children.item(0); - if (component) { + if (component) { this.selection!.isRowClick = false; component.data = this.selection; } diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts index 97530e60f..b11d92eec 100644 --- a/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts +++ b/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts @@ -176,6 +176,7 @@ export class TabPaneCurrent extends BaseElement { */ private eventHandler(): void { let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf; + tr[0].querySelector('#text-input')!.disabled = true; tr[0].querySelector('.removeAll')!.addEventListener('click', (evt: any) => { this.systemTrace!.slicesList = []; let slicesTimeList = [...this.slicesTimeList]; diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts index cf09f48f4..bc5383e2d 100644 --- a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts +++ b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts @@ -16,6 +16,7 @@ import { BaseElement, element } from '../../../../base-ui/BaseElement'; import { type LitTable } from '../../../../base-ui/table/lit-table'; import '../../../../base-ui/table/lit-table-column'; +import { AllAppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAllAppStartup'; import { queryBinderArgsByArgset, @@ -455,7 +456,8 @@ export class TabPaneCurrentSelection extends BaseElement { scrollCallback: ((d: any) => void) | undefined, scrollWakeUp: (d: any) => void | undefined, scrollPreviousData: (d: any) => void | undefined, - scrollNextData: (d: any) => void | undefined + scrollNextData: (d: any) => void | undefined, + callback: ((data: Array) => void) | undefined = undefined ): void { //线程信息 this.setTableHeight('550px'); @@ -466,6 +468,7 @@ export class TabPaneCurrentSelection extends BaseElement { leftTitle.innerText = 'Thread State'; } let list: any[] = []; + let jankJumperList = new Array(); list.push({ name: 'StartTime(Relative)', value: getTimeString(data.startTime || 0), @@ -583,12 +586,17 @@ export class TabPaneCurrentSelection extends BaseElement { }); }); } + let timeLineNode = new ThreadTreeNode(data.tid!, data.pid!, data.startTime!); + jankJumperList.push(timeLineNode); if (args.length > 0) { args.forEach((arg) => { list.push({ name: arg.keyName, value: arg.strValue }); }); } this.currentSelectionTbl!.dataSource = list; + if (callback) { + callback(jankJumperList); + } this.currentSelectionTbl?.shadowRoot?.querySelector('#next-state-click')?.addEventListener('click', () => { if (scrollNextData) { scrollNextData(data); @@ -816,6 +824,42 @@ export class TabPaneCurrentSelection extends BaseElement { } } + setAllStartupData(data: AllAppStartupStruct, scrollCallback: Function): void { + this.setTableHeight('550px'); + this.initCanvas(); + let allStartUpLeftTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#leftTitle'); + let allStartUpmiddleTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightText'); + let allStartUpRightButton: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightButton'); + if (allStartUpmiddleTitle) allStartUpmiddleTitle.style.visibility = 'hidden'; + if (allStartUpRightButton) allStartUpRightButton.style.visibility = 'hidden'; + if (allStartUpLeftTitle) { + allStartUpLeftTitle.innerText = 'Details'; + } + let list: any[] = []; + list.push({ name: 'Name', value: data.stepName! }); + list.push({ + name: 'StartTime(Relative)', + value: getTimeString(data.startTs || 0), + }); + list.push({ + name: 'StartTime(Absolute)', + value: ((data.startTs || 0) + (window as any).recordStartNS) / 1000000000 + 's', + }); + list.push({ + name: 'EndTime(Relative)', + value: getTimeString((data.startTs || 0) + (data.dur || 0)), + }); + list.push({ + name: 'EndTime(Abslute)', + value: ((data.startTs || 0) + (data.dur || 0) + (window as any).recordStartNS) / 1000000000 + 's', + }); + list.push({ + name: 'Dur', + value: getTimeString(data.dur || 0), + }); + this.currentSelectionTbl!.dataSource = list; + } + setStartupData(data: AppStartupStruct, scrollCallback: Function): void { this.setTableHeight('550px'); this.initCanvas(); @@ -1408,3 +1452,14 @@ export class JankTreeNode { children: Array = []; } + +export class ThreadTreeNode { + tid: number = 0; + pid: number = -1; + startTime: number = 1; + constructor(tid: number, pid: number, startTime: number) { + this.tid = tid; + this.pid = pid; + this.startTime = startTime; + } +} diff --git a/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts b/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts index b0d3a668f..ab0dac27e 100644 --- a/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts +++ b/ide/src/trace/component/trace/timer-shaft/TabPaneFlag.ts @@ -132,6 +132,7 @@ export class TabPaneFlag extends BaseElement { */ private eventHandler(): void { let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf; + tr[0].querySelector('#text-input')!.disabled = true; tr[0].querySelector('.removeAll')!.addEventListener('click', (evt: any) => { this.systemTrace!.flagList = []; let flagList = [...this.flagList]; diff --git a/ide/src/trace/database/SqlLite.ts b/ide/src/trace/database/SqlLite.ts index c2248e044..fde3a3366 100644 --- a/ide/src/trace/database/SqlLite.ts +++ b/ide/src/trace/database/SqlLite.ts @@ -1436,6 +1436,35 @@ order by start_name;`, { $pid: pid } ); + export const queryProcessAllAppStartup = (pids: Array): Promise> => + query( + 'queryProcessStartup', + ` + select + P.pid, + A.tid, + A.call_id as itid, + (case when A.start_time < B.start_ts then 0 else (A.start_time - B.start_ts) end) as startTs, + (case + when A.start_time < B.start_ts then (A.end_time - B.start_ts) + when A.end_time = -1 then 0 + else (A.end_time - A.start_time) end) as dur, + A.start_name as startName +from app_startup A,trace_range B +left join process P on A.ipid = P.ipid +where P.pid in(${pids.join(',')}) +order by start_name;`, + { $pid: pids } + ); + + export const querySingleAppStartupsName = (pid:number): Promise> => + query( + 'queryAllAppStartupsName', + `select name from process + where pid=$pid`, + { $pid: pid } + ); + export const queryProcessSoMaxDepth = (): Promise> => query( 'queryProcessSoMaxDepth', diff --git a/ide/src/trace/database/ui-worker/ProcedureWorker.ts b/ide/src/trace/database/ui-worker/ProcedureWorker.ts index 906db554b..df8360f91 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorker.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorker.ts @@ -58,6 +58,7 @@ import { SnapshotRender } from './ProcedureWorkerSnapshot'; import { LogRender } from './ProcedureWorkerLog'; import { HiPerfCallChartRender } from './ProcedureWorkerHiPerfCallChart'; import { HiSysEventRender } from './ProcedureWorkerHiSysEvent'; +import { AllAppStartupRender } from './ProcedureWorkerAllAppStartup'; let dataList: any = {}; let dataList2: any = {}; @@ -77,6 +78,7 @@ export let renders: any = { 'file-system-cell': new FileSystemRender(), process: new ProcessRender(), 'app-start-up': new AppStartupRender(), + 'all-app-start-up': new AllAppStartupRender(), 'app-so-init': new SoRender(), heap: new HeapRender(), 'heap-timeline': new HeapTimelineRender(), diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerAllAppStartup.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerAllAppStartup.ts new file mode 100644 index 000000000..b39d47762 --- /dev/null +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerAllAppStartup.ts @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BaseStruct, dataFilterHandler, drawString } from './ProcedureWorkerCommon'; +import { TraceRow } from '../../component/trace/base/TraceRow'; +import { ColorUtils } from '../../component/trace/base/ColorUtils'; +import { querySingleAppStartupsName } from '../SqlLite'; + +export class AllAppStartupRender { + renderMainThread( + req: { + appStartupContext: CanvasRenderingContext2D; + useCache: boolean; + type: string; + }, + appStartUpRow: TraceRow + ): void { + let list = appStartUpRow.dataList; + let filter = appStartUpRow.dataListCache; + dataFilterHandler(list, filter, { + startKey: 'startTs', + durKey: 'dur', + startNS: TraceRow.range?.startNS ?? 0, + endNS: TraceRow.range?.endNS ?? 0, + totalNS: TraceRow.range?.totalNS ?? 0, + frame: appStartUpRow.frame, + paddingTop: 5, + useCache: req.useCache || !(TraceRow.range?.refresh ?? false), + }); + req.appStartupContext.globalAlpha = 0.6; + let find = false; + let offset = 3; + for (let re of filter) { + AllAppStartupStruct.draw(req.appStartupContext, re); + if (appStartUpRow.isHover) { + if ( + re.frame && + appStartUpRow.hoverX >= re.frame.x - offset && + appStartUpRow.hoverX <= re.frame.x + re.frame.width + offset + ) { + AllAppStartupStruct.hoverStartupStruct = re; + find = true; + } + } + } + if (!find && appStartUpRow.isHover) { + AllAppStartupStruct.hoverStartupStruct = undefined; + } + } +} + +const padding = 3; + +export class AllAppStartupStruct extends BaseStruct { + static hoverStartupStruct: AllAppStartupStruct | undefined; + static selectStartupStruct: AllAppStartupStruct | undefined; + dur: number | undefined; + value: string | undefined; + startTs: number | undefined; + pid: number | undefined; + process: string | undefined; + itid: number | undefined; + endItid: number | undefined; + tid: number | undefined; + startName: number | undefined; + stepName: string | undefined; + + static draw(ctx: CanvasRenderingContext2D, data: AllAppStartupStruct): void { + if (data.frame) { + ctx.globalAlpha = 1.0; + ctx.fillStyle = ColorUtils.colorForTid(data.startName!); + ctx.fillRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height); + if (data.frame.width > 7) { + ctx.textBaseline = 'middle'; + ctx.lineWidth = 1; + let draAppName: string | undefined = ''; + if(data.stepName){ + draAppName = `${data.stepName} (${(data.dur! / 1000000).toFixed(2)}ms)`; + } + let textColor = + ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.stepName || '', 0, ColorUtils.FUNC_COLOR.length)]; + ctx.fillStyle = ColorUtils.funcTextColor(textColor); + drawString(ctx, draAppName, 2, data.frame, data); + } + if (data === AllAppStartupStruct.selectStartupStruct) { + ctx.strokeStyle = '#232c5d'; + ctx.lineWidth = 2; + ctx.strokeRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height); + } + } + } + + static async getStartupName(pid: number): Promise { + let singleAppName = await querySingleAppStartupsName(pid); + return singleAppName[0].name; + } +} \ No newline at end of file diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts index 7a2deff49..462810fae 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts @@ -476,6 +476,7 @@ export class Point { export enum LineType { brokenLine, bezierCurve, + StraightLine, } export class PairPoint { @@ -488,6 +489,7 @@ export class PairPoint { lineType?: LineType; business: string = ''; hidden?: boolean = false; + backrowEL?: TraceRow; constructor( rowEL: TraceRow, x: number, @@ -743,97 +745,106 @@ export function drawSelectionRange(context: any, params: TraceRow) { context.globalAlpha = 1; } - // 绘制方法H:RSMainThread::DoComposition平均帧率的箭头指示线条 - if (params._docompositionList?.length) { - const rateList: Array = [...new Set(params.docompositionList)]; - if (rateList.length >= 2) { - // 计算平均帧率 - let cutres: number = (rateList[rateList.length - 1]! - rateList[0]!); - let avgFrameRate: string = ((rateList.length - 1) / cutres * 1000000000).toFixed(1) + 'fps'; - - let avgRateStartX = Math.floor( - ns2x( - rateList[0]!, - TraceRow.range?.startNS ?? 0, - TraceRow.range?.endNS ?? 0, - TraceRow.range?.totalNS ?? 0, - params.frame - ) - ); - let avgRateEndX = Math.floor( - ns2x( - rateList[rateList.length - 1]!, - TraceRow.range?.startNS ?? 0, - TraceRow.range?.endNS ?? 0, - TraceRow.range?.totalNS ?? 0, - params.frame - ) - ); - const textWidth = context.measureText(avgFrameRate).width; - const textHeight = 25; - const padding = 5; - let textX = Math.floor(ns2x( - (rateList[0]! + rateList[rateList.length - 1]!) / 2, - TraceRow.range?.startNS ?? 0, - TraceRow.range?.endNS ?? 0, - TraceRow.range?.totalNS ?? 0, - params.frame - )) - textWidth / 2; - const textY = params.frame.y + 25; + // 绘制方法H:RSMainThread::DoComposition平均帧率的箭头指示线条 + if (params._docompositionList?.length) { + const rateList: Array = [...new Set(params.docompositionList)]; + if (rateList.length >= 2) { + // 计算平均帧率 + let cutres: number = rateList[rateList.length - 1]! - rateList[0]!; + let avgFrameRate: string = (((rateList.length - 1) / cutres) * 1000000000).toFixed(1) + 'fps'; + + let avgRateStartX = Math.floor( + ns2x( + rateList[0]!, + TraceRow.range?.startNS ?? 0, + TraceRow.range?.endNS ?? 0, + TraceRow.range?.totalNS ?? 0, + params.frame + ) + ); + let avgRateEndX = Math.floor( + ns2x( + rateList[rateList.length - 1]!, + TraceRow.range?.startNS ?? 0, + TraceRow.range?.endNS ?? 0, + TraceRow.range?.totalNS ?? 0, + params.frame + ) + ); + const textWidth = context.measureText(avgFrameRate).width; + const textHeight = 25; + const padding = 5; + let textX = + Math.floor( + ns2x( + (rateList[0]! + rateList[rateList.length - 1]!) / 2, + TraceRow.range?.startNS ?? 0, + TraceRow.range?.endNS ?? 0, + TraceRow.range?.totalNS ?? 0, + params.frame + ) + ) - + textWidth / 2; + const textY = params.frame.y + 25; + + //左移到边界,不画线和文字 + if (avgRateStartX <= 0) { + avgRateStartX = -100; + } + if (avgRateEndX <= 0) { + avgRateEndX = -100; + } + if (textX <= 0) { + textX = -100; + } + //右移到边界,不画线和文字 + if (textX + textWidth / 2 >= params.frame.width) { + textX = params.frame.width + 100; + } + if (avgRateStartX >= params.frame.width) { + avgRateStartX = params.frame.width + 100; + } + if (avgRateEndX >= params.frame.width) { + avgRateEndX = params.frame.width + 100; + } + // 绘制文字背景矩形 + context.fillStyle = 'red'; + context.fillRect( + textX - padding, + textY - textHeight + padding, + textWidth + padding * 2, + textHeight - padding * 2 + ); - //左移到边界,不画线和文字 - if (avgRateStartX <= 0) { - avgRateStartX = -100; - } - if (avgRateEndX <= 0) { - avgRateEndX = -100; - } - if (textX <= 0) { - textX = -100; - } - //右移到边界,不画线和文字 - if (textX + textWidth / 2 >= params.frame.width) { - textX = params.frame.width + 100 - } - if (avgRateStartX >= params.frame.width) { - avgRateStartX = params.frame.width + 100; - } - if (avgRateEndX >= params.frame.width) { - avgRateEndX = params.frame.width + 100; - } - // 绘制文字背景矩形 - context.fillStyle = 'red'; - context.fillRect(textX - padding, textY - textHeight + padding, textWidth + padding * 2, textHeight - padding * 2); - - context.lineWidth = 2; - context.strokeStyle = 'yellow'; - context.beginPath(); - context.moveTo(avgRateStartX, textY); - context.lineTo(avgRateEndX, textY); - context.stroke(); - - const arrowSize = 5.5; - const arrowHead = (x: number, y: number, direction: 'left' | 'right') => { + context.lineWidth = 2; + context.strokeStyle = 'yellow'; context.beginPath(); - const headX = x + (direction === 'left' ? arrowSize : -arrowSize); - const headY = y - arrowSize / 2; - context.moveTo(x, y); - context.lineTo(headX, headY); - context.lineTo(headX, y + arrowSize); - context.closePath(); - - context.fillStyle = 'yellow'; - context.fill(); - }; - arrowHead(avgRateStartX, textY - 1, 'left'); - arrowHead(avgRateEndX, textY - 1, 'right'); - - context.fillStyle = 'white'; - context.fillText(avgFrameRate, textX, textY - 8); + context.moveTo(avgRateStartX, textY); + context.lineTo(avgRateEndX, textY); + context.stroke(); + + const arrowSize = 5.5; + const arrowHead = (x: number, y: number, direction: 'left' | 'right') => { + context.beginPath(); + const headX = x + (direction === 'left' ? arrowSize : -arrowSize); + const headY = y - arrowSize / 2; + context.moveTo(x, y); + context.lineTo(headX, headY); + context.lineTo(headX, y + arrowSize); + context.closePath(); + + context.fillStyle = 'yellow'; + context.fill(); + }; + arrowHead(avgRateStartX, textY - 1, 'left'); + arrowHead(avgRateEndX, textY - 1, 'right'); + + context.fillStyle = 'white'; + context.fillText(avgFrameRate, textX, textY - 8); + } } } } -} export function drawWakeUp( wakeUpContext: CanvasRenderingContext2D | any, @@ -973,6 +984,9 @@ export function drawLinkLines( case LineType.bezierCurve: drawBezierCurve([newFirstNode, newSecondNode], maxWidth, context, percentage); break; + case LineType.StraightLine: + drawStraightLine([newFirstNode, newSecondNode], maxWidth, context); + break; default: drawBezierCurve([newFirstNode, newSecondNode], maxWidth, context, percentage); } @@ -1059,6 +1073,65 @@ function drawBezierCurve(it: PairPoint[], maxWidth: number, context: CanvasRende } } +function drawStraightLine(it: PairPoint[], maxWidth: number, context: CanvasRenderingContext2D) { + let startPoint = it[0].x > it[1].x ? it[1] : it[0]; + let endPoint = it[0].x > it[1].x ? it[0] : it[1]; + + let arrowSize = 8; + if (startPoint && endPoint) { + //左移到边界,不画线 + if (startPoint.x <= 0) { + startPoint.x = -100; + } + if (endPoint.x <= 0) { + endPoint.x = -100; + } + //右移到边界,不画线 + if (startPoint.x >= maxWidth) { + startPoint.x = maxWidth + 100; + } + if (endPoint.x >= maxWidth) { + endPoint.x = maxWidth + 100; + } + + context.beginPath(); + context.lineWidth = 2; + context.strokeStyle = '#0000FF'; + + context.moveTo(startPoint.x, startPoint.y); + context.lineTo(endPoint.x, endPoint.y); + + // 绘制箭头 + let arrow = Math.atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x); + context.moveTo(endPoint.x, endPoint.y); + context.lineTo( + endPoint.x - arrowSize * Math.cos(arrow - Math.PI / 6), + endPoint.y - arrowSize * Math.sin(arrow - Math.PI / 6) + ); + context.moveTo(endPoint.x, endPoint.y); + context.lineTo( + endPoint.x - arrowSize * Math.cos(arrow + Math.PI / 6), + endPoint.y - arrowSize * Math.sin(arrow + Math.PI / 6) + ); + + // 绘制另一端箭头 + arrow = Math.atan2(startPoint.y - endPoint.y, startPoint.x - endPoint.x); + context.moveTo(startPoint.x, startPoint.y); + context.lineTo( + startPoint.x - arrowSize * Math.cos(arrow - Math.PI / 6), + startPoint.y - arrowSize * Math.sin(arrow - Math.PI / 6) + ); + context.moveTo(startPoint.x, startPoint.y); + context.lineTo( + startPoint.x - arrowSize * Math.cos(arrow + Math.PI / 6), + startPoint.y - arrowSize * Math.sin(arrow + Math.PI / 6) + ); + + context.stroke(); + context.closePath(); + } +} + function drawBrokenLine(it: PairPoint[], maxWidth: number, context: CanvasRenderingContext2D): void { let brokenLineStart = it[0].x > it[1].x ? it[1] : it[0]; let brokenLineEnd = it[0].x > it[1].x ? it[0] : it[1]; diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts index 23c168151..aec83744c 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerThread.ts @@ -71,6 +71,7 @@ export class ThreadStruct extends BaseThreadStruct { static sColor = '#FBFBFB'; static hoverThreadStruct: ThreadStruct | undefined; static selectThreadStruct: ThreadStruct | undefined; + static selectThreadStructList: Array = new Array(); argSetID: number | undefined; translateY: number | undefined; textMetricsWidth: number | undefined; -- Gitee From 1c1334dfdcaff663a232e265131e939a0cf114ad Mon Sep 17 00:00:00 2001 From: zhangzepeng Date: Tue, 5 Dec 2023 19:16:50 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E2=80=981.=E4=BF=AE=E5=A4=8DTaskPool?= =?UTF-8?q?=E7=AC=AC=E4=B8=80=E6=AC=A1=E7=82=B9=E5=87=BB=E6=97=B6Frame?= =?UTF-8?q?=E9=A1=B5Tab=E6=95=B0=E6=8D=AE=E4=B8=BA=E7=A9=BA=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=982.=E5=B1=8F=E8=94=BD=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E7=8A=B6=E6=80=81=E8=B7=B3=E8=BD=AC=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=BC=95=E5=AF=BC=E7=BA=BF3.=E4=BF=AE=E5=A4=8Dhilog?= =?UTF-8?q?=E6=9C=80=E5=90=8E=E4=B8=80=E8=A1=8C=E6=95=B0=E6=8D=AE=E4=B8=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98=E2=80=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzepeng --- ide/package.json | 26 +++++++------------ ide/src/trace/component/SpSystemTrace.ts | 6 ++--- .../component/trace/base/TraceRowConfig.ts | 12 +++++---- .../trace/component/trace/base/TraceSheet.ts | 4 ++- ide/src/trace/database/TraceWorker.ts | 6 ++++- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/ide/package.json b/ide/package.json index 0f4542b70..6e9f13f52 100644 --- a/ide/package.json +++ b/ide/package.json @@ -55,30 +55,24 @@ "@babel/preset-typescript": "*", "@types/jest": "*", "@types/node": "^17.0.10", - "@typescript-eslint/eslint-plugin": "^5.59.9", - "@typescript-eslint/parser": "^5.59.11", - "@webpack-cli/generators": "^3.0.7", - "autoprefixer": "^10.4.14", - "babel-loader": "^9.1.3", - "clean-webpack-plugin": "^4.0.0", - "copy-webpack-plugin": "^11.0.0", - "css-loader": "^6.8.1", - "eslint": "^8.43.0", - "html-webpack-plugin": "^5.5.3", - "javascript-obfuscator": "^4.1.0", + "typescript": "^5.2.2", + "usb": "^2.4.2", "jest": "*", "jest-canvas-mock": "^2.3.1", "jest-environment-jsdom": "^28.1.0", "jsdom-worker": "^0.2.1", "log4js": "^6.4.4", - "mini-css-extract-plugin": "^2.7.6", "node-fetch": "^2.6.7", - "prettier": "^3.0.0", + "autoprefixer": "^10.4.14", + "babel-loader": "^9.1.3", + "css-loader": "^6.8.1", + "mini-css-extract-plugin": "^2.7.6", "style-loader": "^3.3.3", "ts-loader": "^9.4.4", - "typescript": "^5.2.2", - "usb": "^2.4.2", - "wasm-loader": "^1.3.0", + "@webpack-cli/generators": "^3.0.7", + "clean-webpack-plugin": "^4.0.0", + "copy-webpack-plugin": "^11.0.0", + "html-webpack-plugin": "^5.5.3", "webpack": "^5.89.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1" diff --git a/ide/src/trace/component/SpSystemTrace.ts b/ide/src/trace/component/SpSystemTrace.ts index 738015b54..b7c1138b2 100644 --- a/ide/src/trace/component/SpSystemTrace.ts +++ b/ide/src/trace/component/SpSystemTrace.ts @@ -2840,7 +2840,6 @@ export class SpSystemTrace extends BaseElement { ); } this.hoverStructNull(); - let flag = JSON.parse(JSON.stringify(ThreadStruct.selectThreadStruct)); this.selectStructNull(); this.wakeupListNull(); ThreadStruct.hoverThreadStruct = findEntry; @@ -2858,7 +2857,7 @@ export class SpSystemTrace extends BaseElement { let endParentRow = this.shadowRoot?.querySelector>( `trace-row[row-id='${data.pid}'][folder]` ); - this.drawThreadLine(endParentRow, flag, data); + //this.drawThreadLine(endParentRow, ThreadStruct.selectThreadStruct, data); }); } ); @@ -3703,7 +3702,8 @@ export class SpSystemTrace extends BaseElement { } } - drawThreadLine(endParentRow: any, selectThreadStruct: ThreadStruct, data: any) { + drawThreadLine(endParentRow: any, selectThreadStruct: ThreadStruct + | undefined, data: any) { let collectList = this.favoriteChartListEL!.getCollectRows(); let startRow: any; if (selectThreadStruct == undefined || selectThreadStruct == null) { diff --git a/ide/src/trace/component/trace/base/TraceRowConfig.ts b/ide/src/trace/component/trace/base/TraceRowConfig.ts index cd34b616a..8073c8b56 100644 --- a/ide/src/trace/component/trace/base/TraceRowConfig.ts +++ b/ide/src/trace/component/trace/base/TraceRowConfig.ts @@ -859,7 +859,7 @@ export class TraceRowConfig extends BaseElement { padding-right: 20px; background-color: #F6F6F6; height: 3.4em; - flex-wrap: wrap; + flex-wrap: nowrap; } .config-scene-select { height: auto; @@ -936,9 +936,10 @@ export class TraceRowConfig extends BaseElement { display: flex; align-items: center; justify-content: space-between; - transition: all 0.3s; + /*transition: all 0s;*/ user-select:none; - width: max-content; + width: 80%; + margin-top: 2px; color: #ffffff; cursor: pointer; line-height: 40px; @@ -960,6 +961,7 @@ export class TraceRowConfig extends BaseElement { height: 100%; } .temp-icon { + padding-top:6px; margin-left: 20px; width: 20px; } @@ -978,8 +980,8 @@ export class TraceRowConfig extends BaseElement {
    -
    - +
    +
    Timeline Details
    diff --git a/ide/src/trace/component/trace/base/TraceSheet.ts b/ide/src/trace/component/trace/base/TraceSheet.ts index 6993bcd00..e7615b0da 100644 --- a/ide/src/trace/component/trace/base/TraceSheet.ts +++ b/ide/src/trace/component/trace/base/TraceSheet.ts @@ -847,8 +847,10 @@ export class TraceSheet extends BaseElement { ?.querySelector(`#tabs lit-tabpane[key='${key}']`) ?.children.item(0); if (component) { - this.selection!.isRowClick = false; component.data = this.selection; + if (this.selection) { + this.selection.isRowClick = false; + } } } diff --git a/ide/src/trace/database/TraceWorker.ts b/ide/src/trace/database/TraceWorker.ts index 4ca57a55d..113a24fb8 100644 --- a/ide/src/trace/database/TraceWorker.ts +++ b/ide/src/trace/database/TraceWorker.ts @@ -341,7 +341,11 @@ self.onmessage = async (e: MessageEvent) => { const dataSlice = uint8Array.subarray(wrSize, wrSize + sliceLen); Module.HEAPU8.set(dataSlice, reqBufferAddr); wrSize += sliceLen; - r2 = Module._TraceStreamerParseDataEx(sliceLen); + if (wrSize >= uint8Array.length) { + r2 = Module._TraceStreamerParseDataEx(sliceLen, 1); + } else { + r2 = Module._TraceStreamerParseDataEx(sliceLen, 0); + } if (r2 == -1) { break; } -- Gitee From a26864ea3e29fe877e6ed7a8076ef73235f23d5a Mon Sep 17 00:00:00 2001 From: zhangzepeng Date: Tue, 5 Dec 2023 19:18:43 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E2=80=98fix:1.=E6=94=AF=E6=8C=81ebpf?= =?UTF-8?q?=E5=92=8Cnative=5Fhook=E5=AF=BC=E5=87=BA=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E6=A0=88=E7=94=9F=E6=88=90=E6=96=87=E6=9C=AC=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E7=94=9F=E6=88=90svg=E2=80=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzepeng --- trace_streamer/.gn | 3 +- trace_streamer/build/ohos.gni | 6 + .../prebuilts/patch_hiperf/hiviewdfx_BUILD.gn | 2 +- .../prebuilts/patch_protobuf/protobufbuild.gn | 3 + trace_streamer/src/base/ts_common.h | 4 + .../src/filter/native_hook_filter.cpp | 18 +- trace_streamer/src/main.cpp | 55 +++- trace_streamer/src/parser/common_types.h | 5 +- .../rawtrace_parser/ftrace_event_processor.h | 3 +- .../rawtrace_parser/ftrace_processor.cpp | 26 +- .../parser/rawtrace_parser/ftrace_processor.h | 3 +- .../rawtrace_parser/rawtrace_parser.cpp | 4 +- .../native_hook/native_hook_frame_table.cpp | 2 +- trace_streamer/src/trace_data/BUILD.gn | 1 + .../src/trace_data/trace_data_cache.cpp | 310 ++++++++++++++++-- .../src/trace_data/trace_data_cache.h | 12 + .../src/trace_data/trace_data_cache_base.h | 2 +- .../trace_data/trace_data_cache_reader.cpp | 2 +- .../trace_data/trace_data_cache_writer.cpp | 4 +- .../src/trace_data/trace_stdtype.cpp | 14 +- trace_streamer/src/trace_data/trace_stdtype.h | 13 +- .../trace_streamer_selector.cpp | 14 + .../trace_streamer/trace_streamer_selector.h | 2 + 23 files changed, 400 insertions(+), 108 deletions(-) diff --git a/trace_streamer/.gn b/trace_streamer/.gn index 5d10241c5..74c472e0b 100644 --- a/trace_streamer/.gn +++ b/trace_streamer/.gn @@ -11,4 +11,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -buildconfig = "//gn/CONFIG.gn" \ No newline at end of file +buildconfig = "//gn/CONFIG.gn" +script_executable = "/usr/bin/env" \ No newline at end of file diff --git a/trace_streamer/build/ohos.gni b/trace_streamer/build/ohos.gni index 867dcbd2d..8b30ab633 100644 --- a/trace_streamer/build/ohos.gni +++ b/trace_streamer/build/ohos.gni @@ -136,5 +136,11 @@ template("ohos_executable") { if (defined(invoker.ohos_test)) { ohos_test = invoker.ohos_test } + if (defined(invoker.output_extension)) { + output_extension = invoker.output_extension + } + if (is_mingw) { + output_extension = "exe" + } } } diff --git a/trace_streamer/prebuilts/patch_hiperf/hiviewdfx_BUILD.gn b/trace_streamer/prebuilts/patch_hiperf/hiviewdfx_BUILD.gn index a0afe8d68..04ea0f2cf 100644 --- a/trace_streamer/prebuilts/patch_hiperf/hiviewdfx_BUILD.gn +++ b/trace_streamer/prebuilts/patch_hiperf/hiviewdfx_BUILD.gn @@ -61,7 +61,7 @@ ohos_source_set("hiviewdfx_source") { "${THIRD_PARTY}/perf_include/hiviewdfx/faultloggerd/interfaces/innerkits/unwinder/dfx_symbols.cpp", ] if (is_debug) { - sources += ["${THIRD_PARTY}/perf_include/hiviewdfx/faultloggerd/interfaces/innerkits/unwinder/dfx_accessor.cpp",] + sources += [ "${THIRD_PARTY}/perf_include/hiviewdfx/faultloggerd/interfaces/innerkits/unwinder/dfx_accessors.cpp" ] } } diff --git a/trace_streamer/prebuilts/patch_protobuf/protobufbuild.gn b/trace_streamer/prebuilts/patch_protobuf/protobufbuild.gn index 803128c4b..9975dbbc8 100644 --- a/trace_streamer/prebuilts/patch_protobuf/protobufbuild.gn +++ b/trace_streamer/prebuilts/patch_protobuf/protobufbuild.gn @@ -320,5 +320,8 @@ if (use_wasm) { "-Wno-sign-compare", "-D HAVE_PTHREAD", ] + if (is_mingw) { + output_extension = "exe" + } } } diff --git a/trace_streamer/src/base/ts_common.h b/trace_streamer/src/base/ts_common.h index a1170c994..75d609b36 100644 --- a/trace_streamer/src/base/ts_common.h +++ b/trace_streamer/src/base/ts_common.h @@ -21,6 +21,8 @@ #include #include using ClockId = uint32_t; +constexpr size_t G_CHUNK_SIZE = 1024 * 1024; +constexpr size_t FLUSH_CHUNK_THRESHOLD = G_CHUNK_SIZE - 10000; const std::string INVALID_STRING = "INVALID_STRING"; const uint64_t INVALID_ITID = std::numeric_limits::max(); const uint64_t INVALID_IPID = std::numeric_limits::max(); @@ -40,6 +42,7 @@ const uint64_t SEC_TO_NS = 1000 * 1000 * 1000; const int32_t STR_DEFAULT_LEN = -1; const auto INVALID_CPU = INVALID_UINT32; const auto INVALID_TIME = INVALID_UINT64; +const std::string HEX_PREFIX = "0x"; const std::string MEM_QUERY = "select max(value) as maxNum, min(value) as minNum, avg(value) as avgNum, filter.name as name, p.name as " "processName from process_measure left join process_measure_filter as filter on filter.id= filter_id left join " @@ -200,6 +203,7 @@ enum DataSourceType { DATA_SOURCE_TYPE_JSMEMORY_CONFIG, DATA_SOURCE_TYPE_MEM_CONFIG }; +enum HookMemoryType { MALLOC = 0, MMAP = 1, FILE_PAGE_MSG = 2, MEMORY_USING_MSG = 3 }; using DataIndex = uint64_t; using TableRowId = int32_t; using InternalPid = uint32_t; diff --git a/trace_streamer/src/filter/native_hook_filter.cpp b/trace_streamer/src/filter/native_hook_filter.cpp index 4afd5532f..c48e799cc 100644 --- a/trace_streamer/src/filter/native_hook_filter.cpp +++ b/trace_streamer/src/filter/native_hook_filter.cpp @@ -590,7 +590,7 @@ inline void NativeHookFilter::FillOfflineSymbolizationFrames( auto curCacheIpid = mapItor->second->back(); stackIdToCallChainIdMap_.insert(std::make_pair(mapItor->first, ++callChainId_)); auto framesInfo = OfflineSymbolization(mapItor->second); - uint64_t depth = 0; + uint16_t depth = 0; uint64_t filePathIndex = INVALID_UINT64; if (isSingleProcData_) { curCacheIpid = SINGLE_PROC_IPID; @@ -602,8 +602,8 @@ inline void NativeHookFilter::FillOfflineSymbolizationFrames( std::string vaddr = base::Uint64ToHexText(frameInfo->symVaddr_); auto row = traceDataCache_->GetNativeHookFrameData()->AppendNewNativeHookFrame( - callChainId_, depth, frameInfo->ip_, INVALID_UINT64, frameInfo->symbolIndex_, filePathIndex, - frameInfo->offset_, frameInfo->symbolOffset_, vaddr); + callChainId_, depth++, frameInfo->ip_, frameInfo->symbolIndex_, filePathIndex, frameInfo->offset_, + frameInfo->symbolOffset_, vaddr); UpdateFilePathIndexToCallStackRowMap(row, filePathIndex); } } @@ -853,7 +853,7 @@ void NativeHookFilter::ParseFramesInCallStackCompressedMode() for (auto stackIdToFramesItor = stackIdToFramesMap_.begin(); stackIdToFramesItor != stackIdToFramesMap_.end(); stackIdToFramesItor++) { auto frameIds = stackIdToFramesItor->second; - uint64_t depth = 0; + uint16_t depth = 0; auto curCacheIpid = frameIds->back(); if (isSingleProcData_) { curCacheIpid = SINGLE_PROC_IPID; @@ -880,8 +880,8 @@ void NativeHookFilter::ParseFramesInCallStackCompressedMode() continue; } auto row = traceDataCache_->GetNativeHookFrameData()->AppendNewNativeHookFrame( - stackIdToFramesItor->first, depth++, reader.ip(), reader.sp(), symbolIndex, filePathIndex, - reader.offset(), reader.symbol_offset()); + stackIdToFramesItor->first, depth++, reader.ip(), symbolIndex, filePathIndex, reader.offset(), + reader.symbol_offset()); UpdateFilePathIndexToCallStackRowMap(row, filePathIndex); } } @@ -895,7 +895,7 @@ void NativeHookFilter::ParseFramesWithOutCallStackCompressedMode() continue; } auto& framesHash = stackHashValueToFramesHashMap_.at(itor->second); - uint64_t depth = 0; + uint16_t depth = 0; for (auto frameHashValueVectorItor = framesHash.crbegin(); frameHashValueVectorItor != framesHash.crend(); frameHashValueVectorItor++) { if (!frameHashToFrameInfoMap_.count(*frameHashValueVectorItor)) { @@ -904,8 +904,8 @@ void NativeHookFilter::ParseFramesWithOutCallStackCompressedMode() } auto& frameInfo = frameHashToFrameInfoMap_.at(*frameHashValueVectorItor); auto row = traceDataCache_->GetNativeHookFrameData()->AppendNewNativeHookFrame( - callChainId, depth++, frameInfo->ip_, frameInfo->sp_, frameInfo->symbolIndex_, - frameInfo->filePathIndex_, frameInfo->offset_, frameInfo->symbolOffset_); + callChainId, depth++, frameInfo->ip_, frameInfo->symbolIndex_, frameInfo->filePathIndex_, + frameInfo->offset_, frameInfo->symbolOffset_); UpdateFilePathIndexToCallStackRowMap(row, frameInfo->filePathIndex_); } } diff --git a/trace_streamer/src/main.cpp b/trace_streamer/src/main.cpp index 2f4b478eb..147cc43b5 100644 --- a/trace_streamer/src/main.cpp +++ b/trace_streamer/src/main.cpp @@ -46,7 +46,6 @@ namespace SysTuning { namespace TraceStreamer { using namespace SysTuning::TraceStreamer; using namespace SysTuning::base; -constexpr size_t G_CHUNK_SIZE = 1024 * 1024; constexpr int G_MIN_PARAM_NUM = 2; constexpr size_t G_FILE_PERMISSION = 664; constexpr uint8_t RAW_TRACE_PARSE_MAX = 2; @@ -72,18 +71,19 @@ void ShowHelpInfo(const char* argv) printf( "trace analyze tool, it can transfer a bytrace/htrace file into a " "SQLite database and save result to a local file trace_streamer.log.\n" - "Usage: %s FILE -e sqlite_out.pb\n" + "Usage: %s FILE -e sqlite_out.db\n" " or %s FILE -c\n" "Options:\n" " -e transfer a trace file into a SQLiteBased DB. with -nm to except meta table\n" " -c command line mode.\n" - " -d dump perf readable text.\n" + " -d dump perf/hook/ebpf readable text.Default dump file path is src path name + `_ReadableText.txt`\n" " -h start HTTP server.\n" " -l , --level=\n" " Show specific level/levels logs with format: level1,level2,level3\n" " Long level string coule be: DEBUG/INFO/WARN/ERROR/FATAL/OFF.\n" " Short level string coule be: D/I/W/E/F/O.\n" " Default level is OFF.\n" + " -o set dump file path.\n" " -s separate arkts-plugin data, and save it in current dir with default filename.\n" " -p Specify the port of HTTP server, default is 9001.\n" " -q select sql from file.\n" @@ -136,14 +136,14 @@ bool ReadAndParser(SysTuning::TraceStreamer::TraceStreamerSelector& ta, int fd) if (!ta.ParseTraceDataSegment(std::move(buf), static_cast(rsize), false, isFinish)) { return false; }; - TS_LOGI("\rLoadingFile:\t%.2f MB\r", static_cast(g_loadSize) / 1E6); + printf("\rLoadingFile:\t%.2f MB\r", static_cast(g_loadSize) / 1E6); } ta.WaitForParserEnd(); auto endTime = (std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch())) .count(); - TS_LOGI("\nParserDuration:\t%u ms", static_cast(endTime - startTime)); - TS_LOGI("ParserSpeed:\t%.2f MB/s", (g_loadSize / (endTime - startTime) / 1E3)); + (void)fprintf(stdout, "\nParserDuration:\t%u ms\n", static_cast(endTime - startTime)); + (void)fprintf(stdout, "ParserSpeed:\t%.2f MB/s\n", (g_loadSize / (endTime - startTime) / 1E3)); return true; } bool SetFileSize(const std::string& traceFilePath) @@ -204,27 +204,27 @@ int ExportDatabase(TraceStreamerSelector& ts, const std::string& sqliteFilePath) metaData->SetParserToolVersion(g_traceStreamerVersion); metaData->SetParserToolPublishDateTime(g_traceStreamerPublishVersion); metaData->SetTraceDataSize(g_loadSize); - TS_LOGI("ExportDatabase begin...\n"); if (ts.ExportDatabase(sqliteFilePath)) { fprintf(stdout, "ExportDatabase failed\n"); ExportStatusToLog(sqliteFilePath, TRACE_PARSER_ABNORMAL); return 1; } - TS_LOGI("ExportDatabase end\n"); } auto endTime = (std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch())) .count(); endTime += 1; // for any exception of endTime == startTime - TS_LOGI("ExportDuration:\t%u ms\n", static_cast(endTime - startTime)); - TS_LOGI("ExportSpeed:\t%.2f MB/s\n", (g_loadSize / (endTime - startTime)) / 1E3); + fprintf(stdout, "ExportDuration:\t%u ms\n", static_cast(endTime - startTime)); + fprintf(stdout, "ExportSpeed:\t%.2f MB/s\n", (g_loadSize / (endTime - startTime)) / 1E3); return 0; } +enum DumpFileType { UNKONW_TYPE = 0, PERF_TYPE, NATIVE_HOOK_TYPE, EBPF_TYPE }; struct TraceExportOption { std::string traceFilePath; std::string sqliteFilePath; - std::string perfReadableTextFilePath; + DumpFileType dumpFileType = DumpFileType::UNKONW_TYPE; + std::string outputFilePath; std::string metricsIndex; std::string sqlOperatorFilePath; bool interactiveState = false; @@ -235,12 +235,27 @@ struct HttpOption { bool enable = false; int port = 9001; }; +bool SetDumpFileType(char** argv, const std::string& dumpFileType, TraceExportOption& traceExportOption) +{ + if (dumpFileType == "perf") { + traceExportOption.dumpFileType = DumpFileType::PERF_TYPE; + } else if (dumpFileType == "hook") { + traceExportOption.dumpFileType = DumpFileType::NATIVE_HOOK_TYPE; + } else if (dumpFileType == "ebpf") { + traceExportOption.dumpFileType = DumpFileType::EBPF_TYPE; + } else { + ShowHelpInfo(argv[0]); + return false; + } + return true; +} int CheckFinal(char** argv, TraceExportOption& traceExportOption, HttpOption& httpOption) { if ((traceExportOption.traceFilePath.empty() || (!traceExportOption.interactiveState && traceExportOption.sqliteFilePath.empty())) && !httpOption.enable && !traceExportOption.separateFile && traceExportOption.metricsIndex.empty() && - traceExportOption.sqlOperatorFilePath.empty() && traceExportOption.perfReadableTextFilePath.empty()) { + traceExportOption.sqlOperatorFilePath.empty() && traceExportOption.outputFilePath.empty() && + traceExportOption.dumpFileType == DumpFileType::UNKONW_TYPE) { ShowHelpInfo(argv[0]); return 1; } @@ -268,12 +283,16 @@ int CheckArgs(int argc, char** argv, TraceExportOption& traceExportOption, HttpO continue; } else if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--dump")) { TS_CHECK_TRUE_RET(CheckArgc(argc, argv, ++i), 1); - traceExportOption.perfReadableTextFilePath = std::string(argv[i]); + TS_CHECK_TRUE_RET(SetDumpFileType(argv, std::string(argv[i]), traceExportOption), 1); continue; } else if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "--query-file")) { TS_CHECK_TRUE_RET(CheckArgc(argc, argv, ++i), 1); traceExportOption.sqlOperatorFilePath = std::string(argv[i]); continue; + } else if (!strcmp(argv[i], "-o") || !strcmp(argv[i], "--out")) { + TS_CHECK_TRUE_RET(CheckArgc(argc, argv, ++i), 1); + traceExportOption.outputFilePath = std::string(argv[i]); + continue; } else if (!strcmp(argv[i], "-i") || !strcmp(argv[i], "--info")) { PrintInformation(); } else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--level")) { @@ -306,6 +325,8 @@ int CheckArgs(int argc, char** argv, TraceExportOption& traceExportOption, HttpO continue; } traceExportOption.traceFilePath = std::string(argv[i]); + auto strVec = SplitStringToVec(traceExportOption.traceFilePath, "."); + traceExportOption.outputFilePath = strVec.front() + "_ReadableText.txt"; } return CheckFinal(argv, traceExportOption, httpOption); } @@ -344,8 +365,12 @@ int main(int argc, char** argv) } return 1; } - if (!tsOption.perfReadableTextFilePath.empty()) { - ts.ExportPerfReadableText(tsOption.perfReadableTextFilePath); + if (tsOption.dumpFileType == DumpFileType::PERF_TYPE) { + ts.ExportPerfReadableText(tsOption.outputFilePath); + } else if (tsOption.dumpFileType == DumpFileType::NATIVE_HOOK_TYPE) { + ts.ExportHookReadableText(tsOption.outputFilePath); + } else if (tsOption.dumpFileType == DumpFileType::EBPF_TYPE) { + ts.ExportEbpfReadableText(tsOption.outputFilePath); } if (tsOption.interactiveState) { MetaData* metaData = ts.GetMetaData(); diff --git a/trace_streamer/src/parser/common_types.h b/trace_streamer/src/parser/common_types.h index c874648cd..5470e7a9f 100644 --- a/trace_streamer/src/parser/common_types.h +++ b/trace_streamer/src/parser/common_types.h @@ -158,10 +158,7 @@ enum RawTraceContentType : uint8_t { CONTENT_TYPE_PRINTK_FORMATS = 31, CONTENT_TYPE_KALLSYMS = 32 }; -enum RawTraceFileType : uint8_t { - FILE_RAW_TRACE = 0, - HM_FILE_RAW_TRACE = 1 -}; +enum RawTraceFileType : uint8_t { FILE_RAW_TRACE = 0, HM_FILE_RAW_TRACE = 1 }; } // namespace TraceStreamer } // namespace SysTuning #endif // _BYTRACE_COMMON_TYPES_H_ diff --git a/trace_streamer/src/parser/rawtrace_parser/ftrace_event_processor.h b/trace_streamer/src/parser/rawtrace_parser/ftrace_event_processor.h index 4b6bfd3c9..d612346f4 100644 --- a/trace_streamer/src/parser/rawtrace_parser/ftrace_event_processor.h +++ b/trace_streamer/src/parser/rawtrace_parser/ftrace_event_processor.h @@ -21,10 +21,9 @@ #include "trace_plugin_result.pb.h" #include "trace_streamer_config.h" -#define HM_EVENT_ID_OFFSET 32768 - namespace SysTuning { namespace TraceStreamer { +constexpr uint32_t HM_EVENT_ID_OFFSET = 32768; using namespace TraceCfg; class FtraceEventProcessor { public: diff --git a/trace_streamer/src/parser/rawtrace_parser/ftrace_processor.cpp b/trace_streamer/src/parser/rawtrace_parser/ftrace_processor.cpp index fd147ba5a..3ad652d68 100644 --- a/trace_streamer/src/parser/rawtrace_parser/ftrace_processor.cpp +++ b/trace_streamer/src/parser/rawtrace_parser/ftrace_processor.cpp @@ -152,10 +152,10 @@ bool FtraceProcessor::HandleEventFormat(const std::string& formatInfo, EventForm auto lastFiledIndex = format.fields.size() - 1; format.eventSize = format.fields[lastFiledIndex].offset + format.fields[lastFiledIndex].size; if (format.eventId >= HM_EVENT_ID_OFFSET) { - for (auto &fmt: format.commonFields) { + for (auto& fmt : format.commonFields) { fmt.offset += offsetof(struct HmTraceHeader, commonType); } - for (auto &fmt: format.fields) { + for (auto& fmt : format.fields) { fmt.offset += offsetof(struct HmTraceHeader, commonType); } format.eventSize += offsetof(struct HmTraceHeader, commonType); @@ -645,13 +645,12 @@ static inline int RmqEntryTotalSize(unsigned int size) return sizeof(struct RmqEntry) + ((size + RMQ_ENTRY_ALIGN_MASK) & (~RMQ_ENTRY_ALIGN_MASK)); } -bool FtraceProcessor::HmParsePageData(FtraceCpuDetailMsg& cpuMsg, - CpuDetailParser& cpuDetailParser, uint8_t* &data) +bool FtraceProcessor::HmParsePageData(FtraceCpuDetailMsg& cpuMsg, CpuDetailParser& cpuDetailParser, uint8_t*& data) { - struct RmqConsumerData *rmqData = (struct RmqConsumerData *)data; + struct RmqConsumerData* rmqData = reinterpret_cast(data); uint64_t timeStampBase = rmqData->timeStamp; - struct RmqEntry *event; - struct HmTraceHeader *header; + struct RmqEntry* event; + struct HmTraceHeader* header; unsigned int evtSize; unsigned int eventId; EventFormat format = {}; @@ -663,13 +662,13 @@ bool FtraceProcessor::HmParsePageData(FtraceCpuDetailMsg& cpuMsg, auto curPtr = rmqData->data; auto endPtr = rmqData->data + rmqData->length; while (curPtr < endPtr) { - event = (struct RmqEntry *)curPtr; + event = (struct RmqEntry*)curPtr; evtSize = event->size; if (evtSize == 0U) { break; } - header = (struct HmTraceHeader *)event->data; + header = reinterpret_cast(event->data); eventId = header->commonType; if (!GetEventFormatById(eventId, format)) { curPtr += RmqEntryTotalSize(evtSize); @@ -681,7 +680,7 @@ bool FtraceProcessor::HmParsePageData(FtraceCpuDetailMsg& cpuMsg, ftraceEvent->set_timestamp(event->timeStampOffset + timeStampBase); ftraceEvent->set_tgid(header->tgid); ftraceEvent->set_comm(header->tcbName); - HandleFtraceEvent(*ftraceEvent, (uint8_t *)header, evtSize, format); + HandleFtraceEvent(*ftraceEvent, reinterpret_cast(header), evtSize, format); std::unique_ptr eventInfo = std::make_unique(); eventInfo->cpuId = cpuMsg.cpu(); eventInfo->eventId = eventId; @@ -689,9 +688,10 @@ bool FtraceProcessor::HmParsePageData(FtraceCpuDetailMsg& cpuMsg, cpuDetailParser.EventAppend(std::move(eventInfo)); num++; } else { - TS_LOGD("mark.debug. evtId = %u evtSize = %u format.eventId = %u format.evtSize = %u" - "format.eventName = %s format.eventType = %s", eventId, evtSize, format.eventId, format.eventSize, - format.eventName.c_str(), format.eventType.c_str()); + TS_LOGD( + "mark.debug. evtId = %u evtSize = %u format.eventId = %u format.evtSize = %u" + "format.eventName = %s format.eventType = %s", + eventId, evtSize, format.eventId, format.eventSize, format.eventName.c_str(), format.eventType.c_str()); } curPtr += RmqEntryTotalSize(evtSize); } diff --git a/trace_streamer/src/parser/rawtrace_parser/ftrace_processor.h b/trace_streamer/src/parser/rawtrace_parser/ftrace_processor.h index 011ccdc30..cd10e4cef 100644 --- a/trace_streamer/src/parser/rawtrace_parser/ftrace_processor.h +++ b/trace_streamer/src/parser/rawtrace_parser/ftrace_processor.h @@ -39,8 +39,7 @@ public: CpuDetailParser& cpuDetailParser, uint8_t page[], size_t size = FTRACE_PAGE_SIZE); - bool HmParsePageData(FtraceCpuDetailMsg& cpuDetailMsg, - CpuDetailParser& cpuDetailParser, uint8_t* &data); + bool HmParsePageData(FtraceCpuDetailMsg& cpuDetailMsg, CpuDetailParser& cpuDetailParser, uint8_t*& data); bool HandleTgids(const std::string& tgids); bool HandleCmdlines(const std::string& cmdlines); diff --git a/trace_streamer/src/parser/rawtrace_parser/rawtrace_parser.cpp b/trace_streamer/src/parser/rawtrace_parser/rawtrace_parser.cpp index 3430100b3..beb23ccd4 100644 --- a/trace_streamer/src/parser/rawtrace_parser/rawtrace_parser.cpp +++ b/trace_streamer/src/parser/rawtrace_parser/rawtrace_parser.cpp @@ -100,8 +100,8 @@ bool RawTraceParser::HmParseCpuRawData(const std::string& buffer) auto endPtr = startPtr + buffer.size(); for (uint8_t* data = const_cast(startPtr); data < endPtr;) { - TS_CHECK_TRUE(ftraceProcessor_->HmParsePageData(*cpuDetail_.get(), *cpuDetailParser_.get(), data), - false, "hm parse page failed!"); + TS_CHECK_TRUE(ftraceProcessor_->HmParsePageData(*cpuDetail_.get(), *cpuDetailParser_.get(), data), false, + "hm parse page failed!"); cpuDetailParser_->FilterAllEvents(*cpuDetail_.get()); } TS_LOGD("mark.debug. HmParseCpuRawData end success"); diff --git a/trace_streamer/src/table/native_hook/native_hook_frame_table.cpp b/trace_streamer/src/table/native_hook/native_hook_frame_table.cpp index f84c7cb52..51edd5438 100644 --- a/trace_streamer/src/table/native_hook/native_hook_frame_table.cpp +++ b/trace_streamer/src/table/native_hook/native_hook_frame_table.cpp @@ -176,7 +176,7 @@ int32_t NativeHookFrameTable::Cursor::Column(int32_t column) const } break; case Index::DEPTH: - sqlite3_result_int64(context_, static_cast(nativeHookFrameInfoObj_.Depths()[CurrentRow()])); + sqlite3_result_int(context_, static_cast(nativeHookFrameInfoObj_.Depths()[CurrentRow()])); break; case Index::IP: if (nativeHookFrameInfoObj_.Ips()[CurrentRow()] != INVALID_UINT64) { diff --git a/trace_streamer/src/trace_data/BUILD.gn b/trace_streamer/src/trace_data/BUILD.gn index 04012932c..159d66608 100644 --- a/trace_streamer/src/trace_data/BUILD.gn +++ b/trace_streamer/src/trace_data/BUILD.gn @@ -67,5 +67,6 @@ ohos_source_set("trace_data") { "${THIRD_PARTY}/protobuf/src", "${THIRD_PARTY}/bounds_checking_function/include", "${THIRD_PARTY}/json/single_include/nlohmann", + "${THIRD_PARTY}/perf_include/hiviewdfx/faultloggerd/interfaces/nonlinux", ] } diff --git a/trace_streamer/src/trace_data/trace_data_cache.cpp b/trace_streamer/src/trace_data/trace_data_cache.cpp index 5637f671b..873561962 100644 --- a/trace_streamer/src/trace_data/trace_data_cache.cpp +++ b/trace_streamer/src/trace_data/trace_data_cache.cpp @@ -83,6 +83,7 @@ #include "native_hook_statistic_table.h" #include "network_table.h" #include "paged_memory_sample_table.h" +#include "parser/ebpf_parser/ebpf_stdtype.h" #include "perf_call_chain_table.h" #include "perf_files_table.h" #include "perf_report_table.h" @@ -116,6 +117,7 @@ namespace SysTuning { namespace TraceStreamer { constexpr uint8_t CPU_ID_FORMAT_WIDTH = 3; +constexpr uint8_t TIME_PRECISION_SIX = 6; TraceDataCache::TraceDataCache() { InitDB(); @@ -283,29 +285,27 @@ void TraceDataCache::ClearHookCommProtos() int32_t TraceDataCache::ExportPerfReadableText(const std::string& outputName, TraceDataDB::ResultCallBack resultCallBack) { -#if !IS_WASM - int32_t fd(base::OpenFile(outputName, O_CREAT | O_RDWR, TS_PERMISSION_RW)); - TS_CHECK_TRUE(fd != -1, 1, "Failed to create file: %s, err:%s", outputName.c_str(), strerror(errno)); - std::unique_ptr> fp(&fd, [](int32_t* fp) { close(*fp); }); - TS_CHECK_TRUE(ftruncate(fd, 0) != -1, 1, "Failed to ftruncate file: %s, err:%s", outputName.c_str(), + int32_t perfFd = base::OpenFile(outputName, O_CREAT | O_RDWR, TS_PERMISSION_RW); + TS_CHECK_TRUE(perfFd != -1, 1, "Failed to create file: %s, err:%s", outputName.c_str(), strerror(errno)); + std::unique_ptr> fp(&perfFd, [](int32_t* fp) { close(*fp); }); + TS_CHECK_TRUE(ftruncate(perfFd, 0) != -1, 1, "Failed to ftruncate file: %s, err:%s", outputName.c_str(), strerror(errno)); -#endif - TS_LOGI("ExportPerfReadableText begin...\n"); - uint8_t curTimePrecision = 6; - std::string buffLine; - for (uint64_t row = 0; row < perfSample_.Size(); ++row) { - std::string procName; + TS_LOGI("ExportPerfReadableText begin..."); + std::string perfBufferLine; + perfBufferLine.reserve(G_CHUNK_SIZE); + for (uint64_t row = 0; row < perfSample_.Size();) { + std::string perfTaskName; std::string cpuIdStr = std::to_string(perfSample_.CpuIds()[row]); std::string eventTypeName; - auto threadId = perfSample_.Tids()[row]; - if (threadId == 0) { + auto perfTaskId = perfSample_.Tids()[row]; + if (perfTaskId == 0) { auto threadDataRow = 0; - procName = GetDataFromDict(GetConstThreadData(threadDataRow).nameIndex_); + perfTaskName = GetDataFromDict(GetConstThreadData(threadDataRow).nameIndex_); } else { - auto perfThreadTidItor = std::find(perfThread_.Tids().begin(), perfThread_.Tids().end(), threadId); + auto perfThreadTidItor = std::find(perfThread_.Tids().begin(), perfThread_.Tids().end(), perfTaskId); if (perfThreadTidItor != perfThread_.Tids().end()) { auto perfThreadRow = std::distance(perfThread_.Tids().begin(), perfThreadTidItor); - procName = GetDataFromDict(perfThread_.ThreadNames()[perfThreadRow]); + perfTaskName = GetDataFromDict(perfThread_.ThreadNames()[perfThreadRow]); } } auto perfReportIdItor = @@ -314,23 +314,29 @@ int32_t TraceDataCache::ExportPerfReadableText(const std::string& outputName, auto perfReportRow = std::distance(perfReport_.IdsData().begin(), perfReportIdItor); eventTypeName = GetDataFromDict(perfReport_.Values()[perfReportRow]); } - buffLine += procName; - buffLine += (" " + std::to_string(threadId)); - buffLine += (" [" + std::string(CPU_ID_FORMAT_WIDTH - cpuIdStr.size(), '0') + cpuIdStr + "]"); - buffLine += (" " + base::ConvertTimestampToSecStr(perfSample_.TimeStampData()[row], curTimePrecision) + ":"); - buffLine += (" " + std::to_string(perfSample_.EventCounts()[row])); - buffLine += (" " + eventTypeName + " \r\n"); - ExportPerfCallChaninText(perfSample_.SampleIds()[row], buffLine); -#if !IS_WASM - TS_CHECK_TRUE(write(fd, buffLine.data(), buffLine.size()) != -1, 1, "Failed to write file: %s, err:%s", - outputName.c_str(), strerror(errno)); -#endif - buffLine.clear(); + perfBufferLine.append(perfTaskName); + perfBufferLine.append(" ").append(std::to_string(perfTaskId)); + perfBufferLine.append(" [") + .append(std::string(CPU_ID_FORMAT_WIDTH - cpuIdStr.size(), '0')) + .append(cpuIdStr) + .append("]"); + perfBufferLine.append(" ") + .append(base::ConvertTimestampToSecStr(perfSample_.TimeStampData()[row], TIME_PRECISION_SIX)) + .append(":"); + perfBufferLine.append(" ").append(std::to_string(perfSample_.EventCounts()[row])); + perfBufferLine.append(" ").append(eventTypeName).append(" \r\n"); + ExportPerfCallChaninText(perfSample_.SampleIds()[row], perfBufferLine); + if (++row != perfSample_.Size() && perfBufferLine.size() < FLUSH_CHUNK_THRESHOLD) { + continue; + } + TS_CHECK_TRUE(write(perfFd, perfBufferLine.data(), perfBufferLine.size()) != -1, 1, + "Failed to write file: %s, err:%s", outputName.c_str(), strerror(errno)); + perfBufferLine.clear(); } - TS_LOGI("ExportPerfReadableText end...\n"); + TS_LOGI("ExportPerfReadableText end..."); return 0; } -void TraceDataCache::ExportPerfCallChaninText(uint32_t callChainId, std::string& buffLine) +void TraceDataCache::ExportPerfCallChaninText(uint32_t callChainId, std::string& bufferLine) { std::stack callChainStackRows; auto perfCallChainItor = @@ -352,11 +358,247 @@ void TraceDataCache::ExportPerfCallChaninText(uint32_t callChainId, std::string& auto perfFileRow = std::distance(perfFiles_.FileIds().begin(), perfFileIdItor); filePath = GetDataFromDict(perfFiles_.FilePaths()[perfFileRow]); } - buffLine += ("\t" + formatIp); - buffLine += (" [" + perfCallChain_.Names()[perfCallChainRow] + "]"); - buffLine += (" (" + filePath + ")\r\n"); + bufferLine.append("\t").append(formatIp); + bufferLine.append(" [").append(perfCallChain_.Names()[perfCallChainRow]).append("]"); + bufferLine.append(" (").append(filePath).append(")\r\n"); + } + bufferLine.append("\r\n"); +} +int32_t TraceDataCache::ExportHookReadableText(const std::string& outputName, + TraceDataDB::ResultCallBack resultCallBack) +{ + int32_t hookFd = base::OpenFile(outputName, O_CREAT | O_RDWR, TS_PERMISSION_RW); + TS_CHECK_TRUE(hookFd != -1, 1, "Failed to create file: %s, err:%s", outputName.c_str(), strerror(errno)); + std::unique_ptr> fp(&hookFd, [](int32_t* fp) { close(*fp); }); + TS_CHECK_TRUE(ftruncate(hookFd, 0) != -1, 1, "Failed to ftruncate file: %s, err:%s", outputName.c_str(), + strerror(errno)); + TS_LOGI("ExportHookReadableText begin..."); + std::string hookBufferLine; + hookBufferLine.reserve(G_CHUNK_SIZE); + ExportHookDataReadableText(hookFd, hookBufferLine); + ExportHookStatisticReadableText(hookFd, hookBufferLine); + TS_LOGI("ExportHookReadableText end..."); + return 0; +} +bool TraceDataCache::ExportHookDataReadableText(int32_t fd, std::string& bufferLine) +{ + for (uint64_t row = 0; row < nativeHookData_.Size();) { + auto itid = nativeHookData_.InternalTidsData()[row]; + auto hookTaskId = internalThreadsData_[itid].tid_; + auto hookTaskName = GetDataFromDict(internalThreadsData_[itid].nameIndex_); + bufferLine.append(hookTaskName); + bufferLine.append(" ").append(std::to_string(hookTaskId)); + bufferLine.append(" ").append("[---]"); // default HookData event cpu id + bufferLine.append(" ") + .append(base::ConvertTimestampToSecStr(nativeHookData_.TimeStampData()[row], TIME_PRECISION_SIX)) + .append(":"); + bufferLine.append(" ").append("1"); // default HookData event event cnt + bufferLine.append(" ").append(nativeHookData_.EventTypes()[row]).append(" \r\n"); + ExportHookCallChaninText(nativeHookData_.CallChainIds()[row], bufferLine); + if (++row != nativeHookData_.Size() && bufferLine.size() < FLUSH_CHUNK_THRESHOLD) { + continue; + } + TS_CHECK_TRUE(write(fd, bufferLine.data(), bufferLine.size()) != -1, false, + "Failed to write HookData file, err:%s", strerror(errno)); + bufferLine.clear(); + } + return true; +} +bool TraceDataCache::ExportHookStatisticReadableText(int32_t fd, std::string& bufferLine) +{ + std::map statisticEventTypeMap = { + {HookMemoryType::MALLOC, "AllocEvent"}, + {HookMemoryType::MMAP, "MmapEvent"}, + {HookMemoryType::FILE_PAGE_MSG, "FilePageEvent"}, + {HookMemoryType::MEMORY_USING_MSG, "MemoryUsingEvent"}}; + for (uint64_t row = 0; row < nativeHookStatisticData_.Size();) { + auto ipid = nativeHookStatisticData_.Ipids()[row]; + auto statisticTaskId = internalProcessesData_[ipid].pid_; + auto statisticTaskName = internalProcessesData_[ipid].cmdLine_; + std::string_view eventType; + auto statisticEventTypeItor = statisticEventTypeMap.find(nativeHookStatisticData_.MemoryTypes()[row]); + if (statisticEventTypeItor != statisticEventTypeMap.end()) { + eventType = statisticEventTypeItor->second; + } + bufferLine.append(statisticTaskName); + bufferLine.append(" ").append(std::to_string(statisticTaskId)); + bufferLine.append(" ").append("[---]"); // default HookStatistic event cpu id + bufferLine.append(" ") + .append(base::ConvertTimestampToSecStr(nativeHookStatisticData_.TimeStampData()[row], TIME_PRECISION_SIX)) + .append(":"); + bufferLine.append(" ").append("1"); // default HookStatistic event event cnt + bufferLine.append(" ").append(eventType).append(" \r\n"); + ExportHookCallChaninText(nativeHookStatisticData_.CallChainIds()[row], bufferLine); + if (++row != nativeHookStatisticData_.Size() && bufferLine.size() < FLUSH_CHUNK_THRESHOLD) { + continue; + } + TS_CHECK_TRUE(write(fd, bufferLine.data(), bufferLine.size()) != -1, false, + "Failed to write HookStatistic file, err:%s", strerror(errno)); + bufferLine.clear(); + } + return true; +} +void TraceDataCache::ExportHookCallChaninText(uint32_t callChainId, std::string& bufferLine) +{ + auto hookFrameCallChainItor = std::lower_bound(nativeHookFrameData_.CallChainIds().begin(), + nativeHookFrameData_.CallChainIds().end(), callChainId); + while (hookFrameCallChainItor != nativeHookFrameData_.CallChainIds().end() && + callChainId == *hookFrameCallChainItor) { + auto hookCallChainRow = std::distance(nativeHookFrameData_.CallChainIds().begin(), hookFrameCallChainItor); + auto hookFrameIp = base::number(nativeHookFrameData_.Ips()[hookCallChainRow], base::INTEGER_RADIX_TYPE_HEX); + hookFrameIp = std::string(base::INTEGER_RADIX_TYPE_HEX - hookFrameIp.size(), ' ') + hookFrameIp; + std::string hookSymName("unknown"); + std::string hookFilePath("[unknown]"); + if (nativeHookFrameData_.SymbolNames()[hookCallChainRow] != INVALID_UINT64) { + hookSymName = GetDataFromDict(nativeHookFrameData_.SymbolNames()[hookCallChainRow]); + } + if (nativeHookFrameData_.FilePaths()[hookCallChainRow] != INVALID_UINT64) { + hookFilePath = GetDataFromDict(nativeHookFrameData_.FilePaths()[hookCallChainRow]); + } + bufferLine.append("\t").append(hookFrameIp); + bufferLine.append(" [").append(hookSymName).append("]"); + bufferLine.append(" (").append(hookFilePath).append(")\r\n"); + ++hookFrameCallChainItor; + } + bufferLine.append("\r\n"); +} +int32_t TraceDataCache::ExportEbpfReadableText(const std::string& outputName, + TraceDataDB::ResultCallBack resultCallBack) +{ + int32_t ebpfFd = base::OpenFile(outputName, O_CREAT | O_RDWR, TS_PERMISSION_RW); + TS_CHECK_TRUE(ebpfFd != -1, 1, "Failed to create file: %s, err:%s", outputName.c_str(), strerror(errno)); + std::unique_ptr> fp(&ebpfFd, [](int32_t* fp) { close(*fp); }); + TS_CHECK_TRUE(ftruncate(ebpfFd, 0) != -1, 1, "Failed to ftruncate file: %s, err:%s", outputName.c_str(), + strerror(errno)); + TS_LOGI("ExportEbpfReadableText begin..."); + EbpfEventTypeMap ebpfEventTypeMap = { + {EbpfStdtype::EBPF_DATA_TYPE::ITEM_EVENT_MAPS, "MapsEvent"}, + {EbpfStdtype::EBPF_DATA_TYPE::ITEM_SYMBOL_INFO, "SymbolEvent"}, + {EbpfStdtype::EBPF_DATA_TYPE::ITEM_EVENT_FS, "FsEvent"}, + {EbpfStdtype::EBPF_DATA_TYPE::ITEM_EVENT_VM, "VmEvent"}, + {EbpfStdtype::EBPF_DATA_TYPE::ITEM_EVENT_BIO, "BioEvent"}, + {EbpfStdtype::EBPF_DATA_TYPE::ITEM_EVENT_STR, "StrEvent"}, + {EbpfStdtype::EBPF_DATA_TYPE::ITEM_EVENT_KENEL_SYMBOL_INFO, "KernelSymbolEvent"}}; + std::string ebpfBufferLine; + ebpfBufferLine.reserve(G_CHUNK_SIZE); + ExportEbpfFileSystemReadableText(ebpfFd, ebpfBufferLine, ebpfEventTypeMap); + ExportEbpfPagedMemReadableText(ebpfFd, ebpfBufferLine, ebpfEventTypeMap); + ExportEbpfBIOReadableText(ebpfFd, ebpfBufferLine, ebpfEventTypeMap); + TS_LOGI("ExportEbpfReadableText end..."); + return 0; +} +bool TraceDataCache::ExportEbpfFileSystemReadableText(int32_t fd, + std::string& bufferLine, + const EbpfEventTypeMap& ebpfEventTypeMap) +{ + for (uint64_t row = 0; row < fileSamplingTableData_.Size();) { + auto fileSysTaskId = internalThreadsData_[fileSamplingTableData_.Itids()[row]].tid_; + auto fileSysTaskName = GetDataFromDict(internalThreadsData_[fileSamplingTableData_.Itids()[row]].nameIndex_); + std::string_view fileSampleEventType; + auto ebpfEventTypeItor = ebpfEventTypeMap.find(fileSamplingTableData_.Types()[row]); + if (ebpfEventTypeItor != ebpfEventTypeMap.end()) { + fileSampleEventType = ebpfEventTypeItor->second; + } + bufferLine.append(fileSysTaskName); + bufferLine.append(" ").append(std::to_string(fileSysTaskId)); + bufferLine.append(" ").append("[---]"); // default FileSystem event cpu id + bufferLine.append(" ") + .append(base::ConvertTimestampToSecStr(fileSamplingTableData_.StartTs()[row], TIME_PRECISION_SIX)) + .append(":"); + bufferLine.append(" ").append("1"); // default FileSystem event cnt + bufferLine.append(" ").append(fileSampleEventType).append(" \r\n"); + ExportEbpfCallChaninText(fileSamplingTableData_.CallChainIds()[row], bufferLine); + if (++row != fileSamplingTableData_.Size() && bufferLine.size() < FLUSH_CHUNK_THRESHOLD) { + continue; + } + TS_CHECK_TRUE(write(fd, bufferLine.data(), bufferLine.size()) != -1, false, + "Failed to write FileSystem event file err:%s", strerror(errno)); + bufferLine.clear(); + } + return true; +} +bool TraceDataCache::ExportEbpfPagedMemReadableText(int32_t fd, + std::string& bufferLine, + const EbpfEventTypeMap& ebpfEventTypeMap) +{ + for (uint64_t row = 0; row < pagedMemorySampleData_.Size();) { + auto pagedMemTaskId = internalThreadsData_[pagedMemorySampleData_.Itids()[row]].tid_; + auto pagedMemTaskName = GetDataFromDict(internalThreadsData_[pagedMemorySampleData_.Itids()[row]].nameIndex_); + std::string_view pageMemEventType; + auto ebpfEventTypeItor = ebpfEventTypeMap.find(pagedMemorySampleData_.Types()[row]); + if (ebpfEventTypeItor != ebpfEventTypeMap.end()) { + pageMemEventType = ebpfEventTypeItor->second; + } + bufferLine.append(pagedMemTaskName); + bufferLine.append(" ").append(std::to_string(pagedMemTaskId)); + bufferLine.append(" ").append("[---]"); // default PagedMem event cpu id + bufferLine.append(" ") + .append(base::ConvertTimestampToSecStr(pagedMemorySampleData_.StartTs()[row], TIME_PRECISION_SIX)) + .append(":"); + bufferLine.append(" ").append("1"); // default PagedMem event cnt + bufferLine.append(" ").append(pageMemEventType).append(" \r\n"); + ExportEbpfCallChaninText(pagedMemorySampleData_.CallChainIds()[row], bufferLine); + if (++row != pagedMemorySampleData_.Size() && bufferLine.size() < FLUSH_CHUNK_THRESHOLD) { + continue; + } + TS_CHECK_TRUE(write(fd, bufferLine.data(), bufferLine.size()) != -1, false, + "Failed to write PagedMem event file err:%s", strerror(errno)); + bufferLine.clear(); + } + return true; +} +bool TraceDataCache::ExportEbpfBIOReadableText(int32_t fd, + std::string& bufferLine, + const EbpfEventTypeMap& ebpfEventTypeMap) +{ + for (uint64_t row = 0; row < bioLatencySampleData_.Size();) { + auto bioTaskId = internalThreadsData_[bioLatencySampleData_.Itids()[row]].tid_; + auto bioTaskName = GetDataFromDict(internalThreadsData_[bioLatencySampleData_.Itids()[row]].nameIndex_); + std::string_view bioEventType; + auto ebpfEventTypeItor = ebpfEventTypeMap.find(bioLatencySampleData_.Types()[row]); + if (ebpfEventTypeItor != ebpfEventTypeMap.end()) { + bioEventType = ebpfEventTypeItor->second; + } + bufferLine.append(bioTaskName); + bufferLine.append(" ").append(std::to_string(bioTaskId)); + bufferLine.append(" ").append("[---]"); // default BIO event cpu id + bufferLine.append(" ") + .append(base::ConvertTimestampToSecStr(bioLatencySampleData_.StartTs()[row], TIME_PRECISION_SIX)) + .append(":"); + bufferLine.append(" ").append("1"); // default BIO event cnt + bufferLine.append(" ").append(bioEventType).append(" \r\n"); + ExportEbpfCallChaninText(bioLatencySampleData_.CallChainIds()[row], bufferLine); + if (++row != bioLatencySampleData_.Size() && bufferLine.size() < FLUSH_CHUNK_THRESHOLD) { + continue; + } + TS_CHECK_TRUE(write(fd, bufferLine.data(), bufferLine.size()) != -1, false, + "Failed to write BIO event file err:%s", strerror(errno)); + bufferLine.clear(); + } + return true; +} +void TraceDataCache::ExportEbpfCallChaninText(uint32_t callChainId, std::string& bufferLine) +{ + auto ebpfCallChainItor = std::lower_bound(ebpfCallStackData_.CallChainIds().begin(), + ebpfCallStackData_.CallChainIds().end(), callChainId); + while (ebpfCallChainItor != ebpfCallStackData_.CallChainIds().end() && callChainId == *ebpfCallChainItor) { + auto ebpfCallChainRow = std::distance(ebpfCallStackData_.CallChainIds().begin(), ebpfCallChainItor); + auto ebpfFrameIp = GetDataFromDict(ebpfCallStackData_.Ips()[ebpfCallChainRow]).substr(HEX_PREFIX.size()); + ebpfFrameIp = std::string(base::INTEGER_RADIX_TYPE_HEX - ebpfFrameIp.size(), ' ') + ebpfFrameIp; + std::string ebpfSymName("unknown"); + std::string ebpfFilePath("[unknown]"); + if (ebpfCallStackData_.SymbolIds()[ebpfCallChainRow] != INVALID_UINT64) { + ebpfSymName = GetDataFromDict(ebpfCallStackData_.SymbolIds()[ebpfCallChainRow]); + } + if (ebpfCallStackData_.FilePathIds()[ebpfCallChainRow] != INVALID_UINT64) { + ebpfFilePath = GetDataFromDict(ebpfCallStackData_.FilePathIds()[ebpfCallChainRow]); + } + bufferLine.append("\t").append(ebpfFrameIp); + bufferLine.append(" [").append(ebpfSymName).append("]"); + bufferLine.append(" (").append(ebpfFilePath).append(")\r\n"); + ++ebpfCallChainItor; } - buffLine += "\r\n"; + bufferLine.append("\r\n"); } } // namespace TraceStreamer } // namespace SysTuning diff --git a/trace_streamer/src/trace_data/trace_data_cache.h b/trace_streamer/src/trace_data/trace_data_cache.h index 23dc3a945..d9e98423e 100644 --- a/trace_streamer/src/trace_data/trace_data_cache.h +++ b/trace_streamer/src/trace_data/trace_data_cache.h @@ -46,10 +46,22 @@ public: std::deque>& HookCommProtos(); void ClearHookCommProtos(); int32_t ExportPerfReadableText(const std::string& outputName, TraceDataDB::ResultCallBack resultCallBack = nullptr); + int32_t ExportHookReadableText(const std::string& outputName, TraceDataDB::ResultCallBack resultCallBack = nullptr); + int32_t ExportEbpfReadableText(const std::string& outputName, TraceDataDB::ResultCallBack resultCallBack = nullptr); private: void InitDB(); void ExportPerfCallChaninText(uint32_t callChainId, std::string& buffLine); + void ExportHookCallChaninText(uint32_t callChainId, std::string& buffLine); + bool ExportHookDataReadableText(int32_t fd, std::string& bufferLine); + bool ExportHookStatisticReadableText(int32_t fd, std::string& bufferLine); + using EbpfEventTypeMap = std::map; + bool ExportEbpfFileSystemReadableText(int32_t fd, + std::string& bufferLine, + const EbpfEventTypeMap& ebpfEventTypeMap); + bool ExportEbpfPagedMemReadableText(int32_t fd, std::string& bufferLine, const EbpfEventTypeMap& ebpfEventTypeMap); + bool ExportEbpfBIOReadableText(int32_t fd, std::string& bufferLine, const EbpfEventTypeMap& ebpfEventTypeMap); + void ExportEbpfCallChaninText(uint32_t callChainId, std::string& bufferLine); private: bool dbInited_ = false; diff --git a/trace_streamer/src/trace_data/trace_data_cache_base.h b/trace_streamer/src/trace_data/trace_data_cache_base.h index 78a7bf4b0..d5b63d37f 100644 --- a/trace_streamer/src/trace_data/trace_data_cache_base.h +++ b/trace_streamer/src/trace_data/trace_data_cache_base.h @@ -138,7 +138,7 @@ public: LiveProcessDetailData liveProcessDetailData_; FileSystemSample fileSamplingTableData_; EbpfCallStackData ebpfCallStackData_; - PagedMemorySampleData PagedMemorySampleData_; + PagedMemorySampleData pagedMemorySampleData_; #if WITH_EBPF_HELP EbpfProcessMaps ebpfProcessMaps_; EbpfElf ebpfElf_; diff --git a/trace_streamer/src/trace_data/trace_data_cache_reader.cpp b/trace_streamer/src/trace_data/trace_data_cache_reader.cpp index 16b87917c..df45e6d6d 100644 --- a/trace_streamer/src/trace_data/trace_data_cache_reader.cpp +++ b/trace_streamer/src/trace_data/trace_data_cache_reader.cpp @@ -281,7 +281,7 @@ const EbpfCallStackData& TraceDataCacheReader::GetConstEbpfCallStackData() const } const PagedMemorySampleData& TraceDataCacheReader::GetConstPagedMemorySampleData() const { - return PagedMemorySampleData_; + return pagedMemorySampleData_; } #if WITH_EBPF_HELP const EbpfProcessMaps& TraceDataCacheReader::GetConstEbpfProcessMaps() const diff --git a/trace_streamer/src/trace_data/trace_data_cache_writer.cpp b/trace_streamer/src/trace_data/trace_data_cache_writer.cpp index 9274963c1..688aa27d5 100644 --- a/trace_streamer/src/trace_data/trace_data_cache_writer.cpp +++ b/trace_streamer/src/trace_data/trace_data_cache_writer.cpp @@ -274,7 +274,7 @@ EbpfCallStackData* TraceDataCacheWriter::GetEbpfCallStack() } PagedMemorySampleData* TraceDataCacheWriter::GetPagedMemorySampleData() { - return &PagedMemorySampleData_; + return &pagedMemorySampleData_; } #if WITH_EBPF_HELP EbpfProcessMaps* TraceDataCacheWriter::GetEbpfProcessMaps() @@ -487,7 +487,7 @@ void TraceDataCacheWriter::Clear() liveProcessDetailData_.Clear(); fileSamplingTableData_.Clear(); ebpfCallStackData_.Clear(); - PagedMemorySampleData_.Clear(); + pagedMemorySampleData_.Clear(); jsHeapFilesData_.Clear(); jsHeapEdgesData_.Clear(); jsHeapInfoData_.Clear(); diff --git a/trace_streamer/src/trace_data/trace_stdtype.cpp b/trace_streamer/src/trace_data/trace_stdtype.cpp index 49a6c0b92..7968c42f2 100644 --- a/trace_streamer/src/trace_data/trace_stdtype.cpp +++ b/trace_streamer/src/trace_data/trace_stdtype.cpp @@ -662,9 +662,8 @@ const std::deque& NativeHook::CurrentSizeDurs() const return currentSizeDurs_; } size_t NativeHookFrame::AppendNewNativeHookFrame(uint32_t callChainId, - uint64_t depth, + uint16_t depth, uint64_t ip, - uint64_t sp, DataIndex symbolName, DataIndex filePath, uint64_t offset, @@ -673,7 +672,6 @@ size_t NativeHookFrame::AppendNewNativeHookFrame(uint32_t callChainId, { callChainIds_.emplace_back(callChainId); ips_.emplace_back(ip); - sps_.emplace_back(sp); depths_.emplace_back(depth); symbolNames_.emplace_back(symbolName); filePaths_.emplace_back(filePath); @@ -683,9 +681,8 @@ size_t NativeHookFrame::AppendNewNativeHookFrame(uint32_t callChainId, return Size() - 1; } size_t NativeHookFrame::AppendNewNativeHookFrame(uint32_t callChainId, - uint64_t depth, + uint16_t depth, uint64_t ip, - uint64_t sp, DataIndex symbolName, DataIndex filePath, uint64_t offset, @@ -693,7 +690,6 @@ size_t NativeHookFrame::AppendNewNativeHookFrame(uint32_t callChainId, { callChainIds_.emplace_back(callChainId); ips_.emplace_back(ip); - sps_.emplace_back(sp); depths_.emplace_back(depth); symbolNames_.emplace_back(symbolName); filePaths_.emplace_back(filePath); @@ -759,7 +755,7 @@ const std::deque& NativeHookFrame::CallChainIds() const { return callChainIds_; } -const std::deque& NativeHookFrame::Depths() const +const std::deque& NativeHookFrame::Depths() const { return depths_; } @@ -767,10 +763,6 @@ const std::deque& NativeHookFrame::Ips() const { return ips_; } -const std::deque& NativeHookFrame::Sps() const -{ - return sps_; -} const std::deque& NativeHookFrame::SymbolNames() const { return symbolNames_; diff --git a/trace_streamer/src/trace_data/trace_stdtype.h b/trace_streamer/src/trace_data/trace_stdtype.h index 8edb46764..f66413327 100644 --- a/trace_streamer/src/trace_data/trace_stdtype.h +++ b/trace_streamer/src/trace_data/trace_stdtype.h @@ -825,17 +825,15 @@ private: class NativeHookFrame { public: size_t AppendNewNativeHookFrame(uint32_t callChainId, - uint64_t depth, + uint16_t depth, uint64_t ip, - uint64_t sp, DataIndex symbolName, DataIndex filePath, uint64_t offset, uint64_t symbolOffset); size_t AppendNewNativeHookFrame(uint32_t callChainId, - uint64_t depth, + uint16_t depth, uint64_t ip, - uint64_t sp, DataIndex symbolName, DataIndex filePath, uint64_t offset, @@ -852,9 +850,8 @@ public: void UpdateFileId(std::map& filePathIdToFilePathName); void UpdateVaddrs(std::deque& vaddrs); const std::deque& CallChainIds() const; - const std::deque& Depths() const; + const std::deque& Depths() const; const std::deque& Ips() const; - const std::deque& Sps() const; const std::deque& SymbolNames() const; const std::deque& FilePaths() const; const std::deque& Offsets() const; @@ -869,7 +866,6 @@ public: callChainIds_.clear(); depths_.clear(); ips_.clear(); - sps_.clear(); symbolNames_.clear(); filePaths_.clear(); offsets_.clear(); @@ -879,9 +875,8 @@ public: private: std::deque callChainIds_ = {}; - std::deque depths_ = {}; + std::deque depths_ = {}; std::deque ips_ = {}; - std::deque sps_ = {}; std::deque symbolNames_ = {}; std::deque filePaths_ = {}; std::deque offsets_ = {}; diff --git a/trace_streamer/src/trace_streamer/trace_streamer_selector.cpp b/trace_streamer/src/trace_streamer/trace_streamer_selector.cpp index acaf03eb6..852ddddc3 100644 --- a/trace_streamer/src/trace_streamer/trace_streamer_selector.cpp +++ b/trace_streamer/src/trace_streamer/trace_streamer_selector.cpp @@ -294,6 +294,20 @@ int32_t TraceStreamerSelector::ExportPerfReadableText(const std::string& outputN return traceDataCache_->ExportPerfReadableText(outputName, resultCallBack); } +int32_t TraceStreamerSelector::ExportHookReadableText(const std::string& outputName, + TraceDataDB::ResultCallBack resultCallBack) +{ + traceDataCache_->UpdateTraceRange(); + return traceDataCache_->ExportHookReadableText(outputName, resultCallBack); +} + +int32_t TraceStreamerSelector::ExportEbpfReadableText(const std::string& outputName, + TraceDataDB::ResultCallBack resultCallBack) +{ + traceDataCache_->UpdateTraceRange(); + return traceDataCache_->ExportEbpfReadableText(outputName, resultCallBack); +} + bool TraceStreamerSelector::ReloadSymbolFiles(std::string& directory, std::vector& symbolsPaths) { TS_LOGE("directory is %s", directory.c_str()); diff --git a/trace_streamer/src/trace_streamer/trace_streamer_selector.h b/trace_streamer/src/trace_streamer/trace_streamer_selector.h index 9a0db4e25..9688a9aa7 100644 --- a/trace_streamer/src/trace_streamer/trace_streamer_selector.h +++ b/trace_streamer/src/trace_streamer/trace_streamer_selector.h @@ -36,6 +36,8 @@ public: static void SetCleanMode(bool cleanMode); int32_t ExportDatabase(const std::string& outputName, TraceDataDB::ResultCallBack resultCallBack = nullptr); int32_t ExportPerfReadableText(const std::string& outputName, TraceDataDB::ResultCallBack resultCallBack = nullptr); + int32_t ExportHookReadableText(const std::string& outputName, TraceDataDB::ResultCallBack resultCallBack = nullptr); + int32_t ExportEbpfReadableText(const std::string& outputName, TraceDataDB::ResultCallBack resultCallBack = nullptr); bool ReloadSymbolFiles(std::string& symbolsPath, std::vector& symbolsPaths); std::vector SearchData(); int32_t OperateDatabase(const std::string& sql); -- Gitee From fd41970b7a69ee125fa68bff40ed6dfa9cbd76fd Mon Sep 17 00:00:00 2001 From: zhangzepeng Date: Tue, 5 Dec 2023 19:21:40 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E2=80=98fix1.smaps=E7=82=B9=E9=80=89Smaple?= =?UTF-8?q?-SmapsTab=E9=A1=B5=E6=B2=A1=E6=9C=89=E6=95=B0=E6=8D=AE=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B52.=E5=A2=9E=E5=8A=A0vsync=E5=8D=95=E6=A1=86?= =?UTF-8?q?=E6=9E=B6=E7=9A=84=E6=9D=A1=E4=BB=B6=E5=87=BD=E6=95=B03.?= =?UTF-8?q?=E4=BF=AE=E6=94=B9trace=E6=8A=93=E5=8F=96buffer=5Fsize=5Fkb?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=A4=A7=E5=B0=8F=E2=80=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzepeng --- ide/src/trace/component/chart/VSync.ts | 4 ++-- .../trace/component/setting/SpProbesConfig.ts | 18 +++++++++--------- .../component/setting/SpRecordTemplate.ts | 2 +- .../trace/sheet/smaps/TabPaneSmapsSample.ts | 11 ++++------- ide/src/trace/database/SqlLite.ts | 6 +++--- 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/ide/src/trace/component/chart/VSync.ts b/ide/src/trace/component/chart/VSync.ts index 1db820567..e870772ac 100644 --- a/ide/src/trace/component/chart/VSync.ts +++ b/ide/src/trace/component/chart/VSync.ts @@ -24,7 +24,7 @@ let vSyncDataList: VSyncData[] = []; let vSyncEnable = false; let isSingle = false; -export function setVSyncDisable(): void{ +export function setVSyncDisable(): void { vSyncEnable = false; } @@ -57,7 +57,7 @@ export const querySingleVSyncData = (): Promise> => FROM callstack JOIN process WHERE process.name = 'render_service' - AND callstack.name like 'H:GenerateVsyncCount%')` + AND (callstack.name like 'H:GenerateVsyncCount%' or callstack.name like 'H:VSyncGenerator::ThreadLoop::Continue%'))` ); /** diff --git a/ide/src/trace/component/setting/SpProbesConfig.ts b/ide/src/trace/component/setting/SpProbesConfig.ts index d3f3582e2..ac676627f 100644 --- a/ide/src/trace/component/setting/SpProbesConfig.ts +++ b/ide/src/trace/component/setting/SpProbesConfig.ts @@ -66,7 +66,7 @@ export class SpProbesConfig extends BaseElement { if (this.ftraceBufferSizeResult?.hasAttribute('percent')) { return Number(this.ftraceBufferSizeResult?.getAttribute('percent')); } - return 20480; + return 102400; } get memoryConfig() { @@ -312,7 +312,7 @@ export class SpProbesConfig extends BaseElement { ftraceBufferSizeSlider.sliderStyle = { minRange: 2048, maxRange: 307200, - defaultValue: '20480', + defaultValue: '102400', resultUnit: 'KB', stepSize: 2, lineColor: 'var(--dark-color3,#46B1E3)', @@ -332,10 +332,10 @@ export class SpProbesConfig extends BaseElement { if (this.ftraceBufferSizeResult!.hasAttribute('percent')) { ftraceBuffSizeResultInput.value = Number(this.ftraceBufferSizeResult!.getAttribute('percent')).toString(); } else { - ftraceBuffSizeResultInput.value = '20480'; + ftraceBuffSizeResultInput.value = '102400'; } }); - ftraceBufferSizeSliderParent.setAttribute('percent', '20480'); + ftraceBufferSizeSliderParent.setAttribute('percent', '102400'); ftraceBuffSizeResultInput.style.color = 'var(--dark-color1,#000000)'; ftraceBuffSizeResultInput.addEventListener('input', (ev) => { if (this.ftraceBufferSizeResult!.hasAttribute('percent')) { @@ -346,7 +346,7 @@ export class SpProbesConfig extends BaseElement { ftraceBuffSizeResultInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; if (ftraceBuffSizeResultInput.value.trim() === '') { ftraceBuffSizeResultInput.style.color = 'red'; - ftraceBufferSizeSliderParent.setAttribute('percent', '20480'); + ftraceBufferSizeSliderParent.setAttribute('percent', '102400'); return; } let ftraceBufferSize = Number(ftraceBuffSizeResultInput.value); @@ -355,7 +355,7 @@ export class SpProbesConfig extends BaseElement { ftraceBufferSize > ftraceBufferSizeSlider!.sliderStyle.maxRange ) { ftraceBuffSizeResultInput.parentElement!.classList.add('border-red'); - ftraceBufferSizeSliderParent.setAttribute('percent', '20480'); + ftraceBufferSizeSliderParent.setAttribute('percent', '102400'); } else { ftraceBuffSizeResultInput.parentElement!.classList.remove('border-red'); ftraceBufferSizeSlider!.percent = ftraceBuffSizeResultInput.value; @@ -368,8 +368,8 @@ export class SpProbesConfig extends BaseElement { ftraceBuffSizeResultInput.addEventListener('focusout', (ev) => { if (ftraceBuffSizeResultInput.value.trim() === '') { ftraceBuffSizeResultInput.parentElement!.classList.remove('border-red'); - ftraceBufferSizeSliderParent.setAttribute('percent', '20480'); - ftraceBuffSizeResultInput.value = '20480'; + ftraceBufferSizeSliderParent.setAttribute('percent', '102400'); + ftraceBuffSizeResultInput.value = '102400'; ftraceBuffSizeResultInput.style.color = 'var(--dark-color,#6a6f77)'; ftraceBufferSizeSliderParent.setAttribute('percent', ftraceBuffSizeResultInput.value); ftraceBufferSizeSliderParent.setAttribute('percentValue', ftraceBuffSizeResultInput.value); @@ -587,7 +587,7 @@ export class SpProbesConfig extends BaseElement {
    - + KB
    diff --git a/ide/src/trace/component/setting/SpRecordTemplate.ts b/ide/src/trace/component/setting/SpRecordTemplate.ts index ea64abc86..47cef3107 100644 --- a/ide/src/trace/component/setting/SpRecordTemplate.ts +++ b/ide/src/trace/component/setting/SpRecordTemplate.ts @@ -152,7 +152,7 @@ export class SpRecordTemplate extends BaseElement { hitraceCategories: hitraceCategories, flushIntervalMs: 1000, hitraceApps: [], - bufferSizeKb: 2048, + bufferSizeKb: 102400, debugOn: false, flushThresholdKb: 4096, clock: 'boot', diff --git a/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsSample.ts b/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsSample.ts index 1dd95e510..d52bd5b8d 100644 --- a/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsSample.ts +++ b/ide/src/trace/component/trace/sheet/smaps/TabPaneSmapsSample.ts @@ -54,7 +54,8 @@ export class TabPaneSmapsSample extends BaseElement { new ResizeObserver(() => { if (this.parentElement?.clientHeight != 0) { // @ts-ignore - this.tblSmapsSample?.shadowRoot?.querySelector('.table').style.height = this.parentElement.clientHeight - 15+ 'px'; + this.tblSmapsSample?.shadowRoot?.querySelector('.table').style.height = + this.parentElement!.clientHeight - 15 + 'px'; this.tblSmapsSample?.reMeauseHeight(); } }).observe(this.parentElement!); @@ -69,7 +70,7 @@ export class TabPaneSmapsSample extends BaseElement { ); } setSmaps(data: SelectionParam): void { - getTabSmapsSampleData(data.rightNs).then((result) => { + getTabSmapsSampleData(data.leftNs).then((result) => { this.tblSmapsSample!.loading = false; this.filteredData(result); }); @@ -185,11 +186,7 @@ export class TabPaneSmapsSample extends BaseElement { } }; } - if ( - detail.key === 'rssStr' || - detail.key === 'sizeStr' || - detail.key === 'resideStr' - ) { + if (detail.key === 'rssStr' || detail.key === 'sizeStr' || detail.key === 'resideStr') { let key = detail.key.substring(0, detail.key.indexOf('Str')); this.sourceSmapsSample.sort(compare(key, detail.sort, 'number')); } else { diff --git a/ide/src/trace/database/SqlLite.ts b/ide/src/trace/database/SqlLite.ts index fde3a3366..7a7b13cfa 100644 --- a/ide/src/trace/database/SqlLite.ts +++ b/ide/src/trace/database/SqlLite.ts @@ -4842,7 +4842,7 @@ export const queryVmTrackerShmSelectionData = (startNs: number, ipid: number): P where startNS = ${startNs} and ipid = ${ipid};`, {} ); -export const getTabSmapsSampleData = (rightNs: number): Promise> => +export const getTabSmapsSampleData = (leftNs: number): Promise> => query( 'getTabSmapsSampleData', ` @@ -4858,8 +4858,8 @@ export const getTabSmapsSampleData = (rightNs: number): Promise> => private_dirty * 1024 as privateDirty,swap * 1024 as swap,swap_pss * 1024 as swapPss FROM smaps A, trace_range AS t - WHERE (startNs) = $rightNs`, - { $rightNs: rightNs }, + WHERE (startNs) = ${leftNs}`, + { $leftNs: leftNs }, 'exec' ); -- Gitee From 8ce5fe6129d8af21bdcf22b1701a524221594bc3 Mon Sep 17 00:00:00 2001 From: zhangzepeng Date: Tue, 5 Dec 2023 19:28:05 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E2=80=99hiperf=E8=BF=9B=E7=A8=8B=E5=90=8D?= =?UTF-8?q?=E6=9C=89=E8=AF=AF=E2=80=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzepeng --- ide/src/trace/database/SqlLite.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ide/src/trace/database/SqlLite.ts b/ide/src/trace/database/SqlLite.ts index 7a7b13cfa..e185d24e7 100644 --- a/ide/src/trace/database/SqlLite.ts +++ b/ide/src/trace/database/SqlLite.ts @@ -2784,7 +2784,7 @@ export const queryPerfThread = (): Promise> => a.process_id as pid, b.thread_name as processName from perf_thread a - left join (select distinct process_id, thread_name from perf_thread) b + left join (select distinct process_id, thread_name from perf_thread where process_id = thread_id) b on a.process_id = b.process_id order by pid;`, {} -- Gitee