ultravisor 1.0.3 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/launch.json +11 -0
- package/.claude/ultravisor-dev-config.json +3 -0
- package/card-audit.json +1545 -0
- package/docs/_sidebar.md +17 -0
- package/docs/css/docuserve.css +73 -0
- package/docs/features/beacon-authentication.md +209 -0
- package/docs/features/beacon-providers.md +1299 -0
- package/docs/features/beacons.md +530 -0
- package/docs/features/capabilities.md +193 -0
- package/docs/features/llm-model-setup.md +505 -0
- package/docs/features/llm.md +262 -0
- package/docs/features/tasks-content-system.md +110 -0
- package/docs/features/tasks-data-transform.md +233 -0
- package/docs/features/tasks-extension.md +36 -0
- package/docs/features/tasks-file-system.md +203 -0
- package/docs/features/tasks-flow-control.md +125 -0
- package/docs/features/tasks-http-client.md +119 -0
- package/docs/features/tasks-llm.md +118 -0
- package/docs/features/tasks-meadow-api.md +163 -0
- package/docs/features/tasks-user-interaction.md +49 -0
- package/docs/features/tasks.md +14 -0
- package/docs/index.html +1 -1
- package/docs/retold-catalog.json +1 -1
- package/docs/retold-keyword-index.json +17374 -5
- package/operation-library/api-data-pipeline.json +143 -0
- package/operation-library/beacon-remote-command.json +72 -0
- package/operation-library/conditional-file-backup.json +143 -0
- package/operation-library/config-processor.json +136 -0
- package/operation-library/csv-data-analysis.json +228 -0
- package/operation-library/csv-to-json.json +160 -0
- package/operation-library/directory-inventory.json +128 -0
- package/operation-library/expression-calculator.json +114 -0
- package/operation-library/file-search-replace.json +175 -0
- package/operation-library/git-status-report.json +368 -0
- package/operation-library/health-check-ping.json +329 -0
- package/operation-library/json-config-merge.json +313 -0
- package/operation-library/llm-embedding-tool-use.json +314 -0
- package/operation-library/llm-multi-turn-analysis.json +322 -0
- package/operation-library/llm-summarize.json +264 -0
- package/operation-library/log-line-counter.json +185 -0
- package/operation-library/meadow-crud-lifecycle.json +264 -0
- package/operation-library/npm-project-validator.json +193 -0
- package/operation-library/rest-api-orchestrator.json +218 -0
- package/operation-library/shell-system-info.json +137 -0
- package/operation-library/simple-echo.json +95 -0
- package/operation-library/template-processor.json +299 -0
- package/operation-library/text-sanitizer.json +176 -0
- package/package.json +12 -8
- package/source/Ultravisor.cjs +30 -3
- package/source/beacon/Ultravisor-Beacon-CLI.cjs +143 -0
- package/source/beacon/Ultravisor-Beacon-CapabilityProvider.cjs +129 -0
- package/source/beacon/Ultravisor-Beacon-Client.cjs +568 -0
- package/source/beacon/Ultravisor-Beacon-Executor.cjs +500 -0
- package/source/beacon/Ultravisor-Beacon-ProviderRegistry.cjs +330 -0
- package/source/beacon/providers/Ultravisor-Beacon-Provider-FileSystem.cjs +331 -0
- package/source/beacon/providers/Ultravisor-Beacon-Provider-LLM.cjs +966 -0
- package/source/beacon/providers/Ultravisor-Beacon-Provider-Shell.cjs +95 -0
- package/source/cli/Ultravisor-CLIProgram.cjs +44 -22
- package/source/cli/commands/Ultravisor-Command-SingleOperation.cjs +29 -18
- package/source/cli/commands/Ultravisor-Command-SingleTask.cjs +62 -19
- package/source/cli/commands/Ultravisor-Command-UpdateTask.cjs +27 -15
- package/source/config/Ultravisor-Default-Command-Configuration.cjs +12 -3
- package/source/services/Ultravisor-Beacon-Coordinator.cjs +966 -0
- package/source/services/Ultravisor-ExecutionEngine.cjs +1093 -0
- package/source/services/Ultravisor-ExecutionManifest.cjs +629 -0
- package/source/services/Ultravisor-Hypervisor-State.cjs +270 -97
- package/source/services/Ultravisor-Hypervisor.cjs +185 -75
- package/source/services/Ultravisor-Schedule-Persistence-Base.cjs +45 -0
- package/source/services/Ultravisor-StateManager.cjs +253 -0
- package/source/services/Ultravisor-TaskTypeRegistry.cjs +213 -0
- package/source/services/persistence/Ultravisor-Schedule-Persistence-JSONFile.cjs +140 -0
- package/source/services/tasks/Ultravisor-BuiltIn-TaskConfigs.cjs +19 -0
- package/source/services/tasks/Ultravisor-TaskHelper-BeaconDispatch.cjs +107 -0
- package/source/services/tasks/Ultravisor-TaskType-Base.cjs +125 -0
- package/source/services/tasks/content-system/Ultravisor-TaskConfigs-ContentSystem.cjs +90 -0
- package/source/services/tasks/content-system/definitions/content-create-folder.json +24 -0
- package/source/services/tasks/content-system/definitions/content-list-files.json +27 -0
- package/source/services/tasks/content-system/definitions/content-read-file.json +26 -0
- package/source/services/tasks/content-system/definitions/content-save-file.json +26 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskConfigs-DataTransform.cjs +577 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskType-ReplaceString.cjs +80 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskType-SetValues.cjs +74 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskType-StringAppender.cjs +90 -0
- package/source/services/tasks/data-transform/definitions/comprehension-intersect.json +24 -0
- package/source/services/tasks/data-transform/definitions/csv-transform.json +24 -0
- package/source/services/tasks/data-transform/definitions/expression-solver.json +20 -0
- package/source/services/tasks/data-transform/definitions/histogram.json +23 -0
- package/source/services/tasks/data-transform/definitions/parse-csv.json +27 -0
- package/source/services/tasks/data-transform/definitions/replace-string.json +27 -0
- package/source/services/tasks/data-transform/definitions/set-values.json +17 -0
- package/source/services/tasks/data-transform/definitions/string-appender.json +22 -0
- package/source/services/tasks/data-transform/definitions/template-string.json +20 -0
- package/source/services/tasks/extension/Ultravisor-TaskConfigs-Extension.cjs +87 -0
- package/source/services/tasks/extension/definitions/beacon-dispatch.json +32 -0
- package/source/services/tasks/file-system/Ultravisor-TaskConfigs-FileSystem.cjs +509 -0
- package/source/services/tasks/file-system/Ultravisor-TaskType-ReadFile.cjs +96 -0
- package/source/services/tasks/file-system/Ultravisor-TaskType-ReadFileBuffered.cjs +123 -0
- package/source/services/tasks/file-system/Ultravisor-TaskType-WriteFile.cjs +106 -0
- package/source/services/tasks/file-system/definitions/copy-file.json +27 -0
- package/source/services/tasks/file-system/definitions/list-files.json +27 -0
- package/source/services/tasks/file-system/definitions/read-file-buffered.json +31 -0
- package/source/services/tasks/file-system/definitions/read-file.json +26 -0
- package/source/services/tasks/file-system/definitions/read-json.json +23 -0
- package/source/services/tasks/file-system/definitions/write-file.json +29 -0
- package/source/services/tasks/file-system/definitions/write-json.json +30 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskConfigs-FlowControl.cjs +353 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskType-IfConditional.cjs +125 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskType-LaunchOperation.cjs +186 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskType-SplitExecute.cjs +164 -0
- package/source/services/tasks/flow-control/definitions/if-conditional.json +25 -0
- package/source/services/tasks/flow-control/definitions/launch-operation.json +27 -0
- package/source/services/tasks/flow-control/definitions/split-execute.json +32 -0
- package/source/services/tasks/http-client/Ultravisor-TaskConfigs-HttpClient.cjs +281 -0
- package/source/services/tasks/http-client/definitions/get-json.json +26 -0
- package/source/services/tasks/http-client/definitions/get-text.json +26 -0
- package/source/services/tasks/http-client/definitions/rest-request.json +32 -0
- package/source/services/tasks/http-client/definitions/send-json.json +28 -0
- package/source/services/tasks/llm/Ultravisor-TaskConfigs-LLM.cjs +605 -0
- package/source/services/tasks/llm/definitions/llm-chat-completion.json +46 -0
- package/source/services/tasks/llm/definitions/llm-embedding.json +31 -0
- package/source/services/tasks/llm/definitions/llm-tool-use.json +42 -0
- package/source/services/tasks/meadow-api/Ultravisor-TaskConfigs-MeadowApi.cjs +341 -0
- package/source/services/tasks/meadow-api/definitions/meadow-count.json +26 -0
- package/source/services/tasks/meadow-api/definitions/meadow-create.json +26 -0
- package/source/services/tasks/meadow-api/definitions/meadow-delete.json +23 -0
- package/source/services/tasks/meadow-api/definitions/meadow-read.json +26 -0
- package/source/services/tasks/meadow-api/definitions/meadow-reads.json +29 -0
- package/source/services/tasks/meadow-api/definitions/meadow-update.json +26 -0
- package/source/services/tasks/shell/Ultravisor-TaskConfigs-Shell.cjs +63 -0
- package/source/services/tasks/shell/definitions/command.json +29 -0
- package/source/services/tasks/user-interaction/Ultravisor-TaskConfigs-UserInteraction.cjs +64 -0
- package/source/services/tasks/user-interaction/Ultravisor-TaskType-ErrorMessage.cjs +55 -0
- package/source/services/tasks/user-interaction/Ultravisor-TaskType-ValueInput.cjs +47 -0
- package/source/services/tasks/user-interaction/definitions/error-message.json +18 -0
- package/source/services/tasks/user-interaction/definitions/value-input.json +23 -0
- package/source/web_server/Ultravisor-API-Server.cjs +849 -124
- package/test/Ultravisor_browser_tests.js +2226 -0
- package/test/Ultravisor_operation_library_tests.js +894 -0
- package/test/Ultravisor_tests.js +4946 -5044
- package/test/workflows/test-content-concatenate-all.json +339 -0
- package/test/workflows/test-content-full-pipeline.json +159 -0
- package/test/workflows/test-content-list-files.json +76 -0
- package/test/workflows/test-content-save-and-read.json +106 -0
- package/webinterface/css/ultravisor-themes.css +668 -0
- package/webinterface/css/ultravisor.css +37 -14
- package/webinterface/docs/card-help/beacon-dispatch.md +30 -0
- package/webinterface/docs/card-help/command.md +27 -0
- package/webinterface/docs/card-help/comprehension-intersect.md +24 -0
- package/webinterface/docs/card-help/content-create-folder.md +22 -0
- package/webinterface/docs/card-help/content-list-files.md +25 -0
- package/webinterface/docs/card-help/content-read-file.md +24 -0
- package/webinterface/docs/card-help/content-save-file.md +24 -0
- package/webinterface/docs/card-help/copy-file.md +25 -0
- package/webinterface/docs/card-help/csv-transform.md +24 -0
- package/webinterface/docs/card-help/end.md +11 -0
- package/webinterface/docs/card-help/error-message.md +16 -0
- package/webinterface/docs/card-help/expression-solver.md +21 -0
- package/webinterface/docs/card-help/get-json.md +24 -0
- package/webinterface/docs/card-help/get-text.md +24 -0
- package/webinterface/docs/card-help/histogram.md +23 -0
- package/webinterface/docs/card-help/if-conditional.md +23 -0
- package/webinterface/docs/card-help/launch-operation.md +25 -0
- package/webinterface/docs/card-help/list-files.md +25 -0
- package/webinterface/docs/card-help/llm-chat-completion.md +43 -0
- package/webinterface/docs/card-help/llm-embedding.md +24 -0
- package/webinterface/docs/card-help/llm-tool-use.md +39 -0
- package/webinterface/docs/card-help/meadow-count.md +24 -0
- package/webinterface/docs/card-help/meadow-create.md +24 -0
- package/webinterface/docs/card-help/meadow-delete.md +19 -0
- package/webinterface/docs/card-help/meadow-read.md +24 -0
- package/webinterface/docs/card-help/meadow-reads.md +27 -0
- package/webinterface/docs/card-help/meadow-update.md +24 -0
- package/webinterface/docs/card-help/parse-csv.md +27 -0
- package/webinterface/docs/card-help/read-file-buffered.md +29 -0
- package/webinterface/docs/card-help/read-file.md +24 -0
- package/webinterface/docs/card-help/read-json.md +21 -0
- package/webinterface/docs/card-help/replace-string.md +25 -0
- package/webinterface/docs/card-help/rest-request.md +30 -0
- package/webinterface/docs/card-help/send-json.md +26 -0
- package/webinterface/docs/card-help/set-values.md +16 -0
- package/webinterface/docs/card-help/split-execute.md +35 -0
- package/webinterface/docs/card-help/start.md +11 -0
- package/webinterface/docs/card-help/string-appender.md +22 -0
- package/webinterface/docs/card-help/template-string.md +21 -0
- package/webinterface/docs/card-help/value-input.md +24 -0
- package/webinterface/docs/card-help/write-file.md +27 -0
- package/webinterface/docs/card-help/write-json.md +28 -0
- package/webinterface/html/index.html +5 -0
- package/webinterface/package.json +13 -4
- package/webinterface/source/Pict-Application-Ultravisor.js +564 -70
- package/webinterface/source/Ultravisor-TimingUtils.js +99 -0
- package/webinterface/source/card-help-content.js +46 -0
- package/webinterface/source/cards/Ultravisor-BuiltIn-CardConfigs.js +174 -0
- package/webinterface/source/cards/Ultravisor-CardConfigGenerator.js +431 -0
- package/webinterface/source/data/ExampleFlow-CSVPipeline.js +231 -0
- package/webinterface/source/data/ExampleFlow-FileProcessor.js +315 -0
- package/webinterface/source/data/ExampleFlow-MeadowPipeline.js +328 -0
- package/webinterface/source/panels/Ultravisor-CardSettingsPanel.js +902 -0
- package/webinterface/source/providers/PictRouter-Ultravisor-Configuration.json +20 -8
- package/webinterface/source/views/PictView-Ultravisor-BeaconList.js +817 -0
- package/webinterface/source/views/PictView-Ultravisor-BottomBar.js +5 -5
- package/webinterface/source/views/PictView-Ultravisor-Dashboard.js +25 -25
- package/webinterface/source/views/PictView-Ultravisor-Documentation.js +856 -0
- package/webinterface/source/views/PictView-Ultravisor-FlowEditor.js +777 -0
- package/webinterface/source/views/PictView-Ultravisor-ManifestList.js +321 -58
- package/webinterface/source/views/PictView-Ultravisor-OperationEdit.js +36 -91
- package/webinterface/source/views/PictView-Ultravisor-OperationList.js +388 -16
- package/webinterface/source/views/PictView-Ultravisor-PendingInput.js +314 -0
- package/webinterface/source/views/PictView-Ultravisor-Schedule.js +521 -65
- package/webinterface/source/views/PictView-Ultravisor-TimingView.js +333 -71
- package/webinterface/source/views/PictView-Ultravisor-TopBar.js +257 -21
- package/webinterface/theme-sampler.html +645 -0
- package/debug/Harness.js +0 -6
- package/source/services/Ultravisor-Operation-Manifest.cjs +0 -160
- package/source/services/Ultravisor-Operation.cjs +0 -200
- package/source/services/Ultravisor-Task.cjs +0 -349
- package/source/services/events/Ultravisor-Hypervisor-Event-Solver.cjs +0 -11
- package/source/services/tasks/Ultravisor-Task-Base.cjs +0 -264
- package/source/services/tasks/Ultravisor-Task-CollectValues.cjs +0 -188
- package/source/services/tasks/Ultravisor-Task-Command.cjs +0 -65
- package/source/services/tasks/Ultravisor-Task-CommandEach.cjs +0 -190
- package/source/services/tasks/Ultravisor-Task-Conditional.cjs +0 -104
- package/source/services/tasks/Ultravisor-Task-DateWindow.cjs +0 -72
- package/source/services/tasks/Ultravisor-Task-GeneratePagedOperation.cjs +0 -336
- package/source/services/tasks/Ultravisor-Task-LaunchOperation.cjs +0 -143
- package/source/services/tasks/Ultravisor-Task-LaunchTask.cjs +0 -146
- package/source/services/tasks/Ultravisor-Task-LineMatch.cjs +0 -158
- package/source/services/tasks/Ultravisor-Task-Request.cjs +0 -56
- package/source/services/tasks/Ultravisor-Task-Solver.cjs +0 -89
- package/source/services/tasks/Ultravisor-Task-TemplateString.cjs +0 -93
- package/source/services/tasks/rest/Ultravisor-Task-GetBinary.cjs +0 -127
- package/source/services/tasks/rest/Ultravisor-Task-GetJSON.cjs +0 -119
- package/source/services/tasks/rest/Ultravisor-Task-GetText.cjs +0 -109
- package/source/services/tasks/rest/Ultravisor-Task-GetXML.cjs +0 -112
- package/source/services/tasks/rest/Ultravisor-Task-RestRequest.cjs +0 -499
- package/source/services/tasks/rest/Ultravisor-Task-SendJSON.cjs +0 -150
- package/source/services/tasks/stagingfiles/Ultravisor-Task-CopyFile.cjs +0 -110
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ListFiles.cjs +0 -89
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadBinary.cjs +0 -87
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadJSON.cjs +0 -67
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadText.cjs +0 -66
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadXML.cjs +0 -69
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteBinary.cjs +0 -95
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteJSON.cjs +0 -96
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteText.cjs +0 -99
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteXML.cjs +0 -102
- package/webinterface/source/views/PictView-Ultravisor-TaskEdit.js +0 -220
- package/webinterface/source/views/PictView-Ultravisor-TaskList.js +0 -248
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const libPictView = require('pict-view');
|
|
2
2
|
|
|
3
|
+
const libTimingUtils = require('../Ultravisor-TimingUtils.js');
|
|
4
|
+
|
|
3
5
|
const _ViewConfiguration =
|
|
4
6
|
{
|
|
5
7
|
ViewIdentifier: "Ultravisor-TimingView",
|
|
@@ -21,13 +23,13 @@ const _ViewConfiguration =
|
|
|
21
23
|
align-items: center;
|
|
22
24
|
margin-bottom: 1.5em;
|
|
23
25
|
padding-bottom: 1em;
|
|
24
|
-
border-bottom: 1px solid
|
|
26
|
+
border-bottom: 1px solid var(--uv-border-subtle);
|
|
25
27
|
}
|
|
26
28
|
.ultravisor-timing-header h1 {
|
|
27
29
|
margin: 0;
|
|
28
30
|
font-size: 2em;
|
|
29
31
|
font-weight: 300;
|
|
30
|
-
color:
|
|
32
|
+
color: var(--uv-text);
|
|
31
33
|
}
|
|
32
34
|
.ultravisor-timing-selector {
|
|
33
35
|
margin-bottom: 1.5em;
|
|
@@ -38,8 +40,8 @@ const _ViewConfiguration =
|
|
|
38
40
|
padding: 0.6em 0.75em;
|
|
39
41
|
}
|
|
40
42
|
.ultravisor-timing-card {
|
|
41
|
-
background:
|
|
42
|
-
border: 1px solid
|
|
43
|
+
background: var(--uv-bg-surface);
|
|
44
|
+
border: 1px solid var(--uv-border-subtle);
|
|
43
45
|
border-radius: 8px;
|
|
44
46
|
padding: 1.5em;
|
|
45
47
|
margin-bottom: 1.5em;
|
|
@@ -58,19 +60,19 @@ const _ViewConfiguration =
|
|
|
58
60
|
font-size: 0.75em;
|
|
59
61
|
text-transform: uppercase;
|
|
60
62
|
letter-spacing: 0.05em;
|
|
61
|
-
color:
|
|
63
|
+
color: var(--uv-text-secondary);
|
|
62
64
|
margin-bottom: 0.25em;
|
|
63
65
|
}
|
|
64
66
|
.ultravisor-timing-stat-value {
|
|
65
67
|
font-size: 1.2em;
|
|
66
68
|
font-weight: 600;
|
|
67
|
-
color:
|
|
69
|
+
color: var(--uv-text);
|
|
68
70
|
}
|
|
69
71
|
.ultravisor-timing-stat-value.complete {
|
|
70
|
-
color:
|
|
72
|
+
color: var(--uv-success);
|
|
71
73
|
}
|
|
72
74
|
.ultravisor-timing-stat-value.error {
|
|
73
|
-
color:
|
|
75
|
+
color: var(--uv-error);
|
|
74
76
|
}
|
|
75
77
|
.ultravisor-timing-chart {
|
|
76
78
|
margin-top: 1.5em;
|
|
@@ -79,7 +81,7 @@ const _ViewConfiguration =
|
|
|
79
81
|
font-size: 0.85em;
|
|
80
82
|
text-transform: uppercase;
|
|
81
83
|
letter-spacing: 0.05em;
|
|
82
|
-
color:
|
|
84
|
+
color: var(--uv-text-secondary);
|
|
83
85
|
margin-bottom: 1em;
|
|
84
86
|
}
|
|
85
87
|
.ultravisor-timing-row {
|
|
@@ -91,7 +93,7 @@ const _ViewConfiguration =
|
|
|
91
93
|
width: 180px;
|
|
92
94
|
flex-shrink: 0;
|
|
93
95
|
font-size: 0.85em;
|
|
94
|
-
color:
|
|
96
|
+
color: var(--uv-text-secondary);
|
|
95
97
|
white-space: nowrap;
|
|
96
98
|
overflow: hidden;
|
|
97
99
|
text-overflow: ellipsis;
|
|
@@ -100,7 +102,7 @@ const _ViewConfiguration =
|
|
|
100
102
|
.ultravisor-timing-row-bar-container {
|
|
101
103
|
flex: 1;
|
|
102
104
|
height: 28px;
|
|
103
|
-
background:
|
|
105
|
+
background: var(--uv-bg-base);
|
|
104
106
|
border-radius: 4px;
|
|
105
107
|
position: relative;
|
|
106
108
|
overflow: hidden;
|
|
@@ -121,26 +123,34 @@ const _ViewConfiguration =
|
|
|
121
123
|
background: linear-gradient(90deg, #c62828, #e53935);
|
|
122
124
|
}
|
|
123
125
|
.ultravisor-timing-row-bar.running {
|
|
124
|
-
background: linear-gradient(90deg,
|
|
126
|
+
background: linear-gradient(90deg, var(--uv-info), #1e88e5);
|
|
125
127
|
}
|
|
126
128
|
.ultravisor-timing-row-bar.other {
|
|
127
|
-
background: linear-gradient(90deg,
|
|
129
|
+
background: linear-gradient(90deg, var(--uv-btn-secondary-bg), #546e7a);
|
|
128
130
|
}
|
|
129
131
|
.ultravisor-timing-row-bar-text {
|
|
130
132
|
font-size: 0.75em;
|
|
131
133
|
color: #fff;
|
|
132
134
|
white-space: nowrap;
|
|
133
|
-
text-shadow: 0 1px 2px
|
|
135
|
+
text-shadow: 0 1px 2px var(--uv-shadow-heavy);
|
|
134
136
|
}
|
|
135
137
|
.ultravisor-timing-row-duration {
|
|
136
138
|
width: 120px;
|
|
137
139
|
flex-shrink: 0;
|
|
138
140
|
font-size: 0.8em;
|
|
139
|
-
color:
|
|
141
|
+
color: var(--uv-text-secondary);
|
|
140
142
|
text-align: right;
|
|
141
143
|
padding-left: 0.75em;
|
|
142
144
|
font-family: monospace;
|
|
143
145
|
}
|
|
146
|
+
.ultravisor-timing-row-count {
|
|
147
|
+
width: 60px;
|
|
148
|
+
flex-shrink: 0;
|
|
149
|
+
font-size: 0.75em;
|
|
150
|
+
color: var(--uv-text-secondary);
|
|
151
|
+
text-align: right;
|
|
152
|
+
padding-left: 0.5em;
|
|
153
|
+
}
|
|
144
154
|
.ultravisor-timing-axis {
|
|
145
155
|
display: flex;
|
|
146
156
|
align-items: center;
|
|
@@ -151,12 +161,12 @@ const _ViewConfiguration =
|
|
|
151
161
|
flex: 1;
|
|
152
162
|
display: flex;
|
|
153
163
|
justify-content: space-between;
|
|
154
|
-
border-top: 1px solid
|
|
164
|
+
border-top: 1px solid var(--uv-border);
|
|
155
165
|
padding-top: 0.35em;
|
|
156
166
|
}
|
|
157
167
|
.ultravisor-timing-axis-tick {
|
|
158
168
|
font-size: 0.7em;
|
|
159
|
-
color:
|
|
169
|
+
color: var(--uv-text-tertiary);
|
|
160
170
|
font-family: monospace;
|
|
161
171
|
}
|
|
162
172
|
.ultravisor-timing-axis-spacer {
|
|
@@ -166,9 +176,56 @@ const _ViewConfiguration =
|
|
|
166
176
|
.ultravisor-timing-empty {
|
|
167
177
|
text-align: center;
|
|
168
178
|
padding: 3em;
|
|
169
|
-
color:
|
|
179
|
+
color: var(--uv-text-tertiary);
|
|
170
180
|
font-style: italic;
|
|
171
181
|
}
|
|
182
|
+
.ultravisor-timing-verbosity-controls {
|
|
183
|
+
display: flex;
|
|
184
|
+
gap: 0.5em;
|
|
185
|
+
margin-bottom: 1em;
|
|
186
|
+
}
|
|
187
|
+
.ultravisor-timing-verbosity-btn {
|
|
188
|
+
padding: 0.35em 0.75em;
|
|
189
|
+
border: 1px solid var(--uv-border);
|
|
190
|
+
border-radius: 4px;
|
|
191
|
+
background: transparent;
|
|
192
|
+
color: var(--uv-text-secondary);
|
|
193
|
+
font-size: 0.8em;
|
|
194
|
+
cursor: pointer;
|
|
195
|
+
}
|
|
196
|
+
.ultravisor-timing-verbosity-btn.active {
|
|
197
|
+
background: #1e3a5f;
|
|
198
|
+
border-color: #42a5f5;
|
|
199
|
+
color: #90caf9;
|
|
200
|
+
}
|
|
201
|
+
.ultravisor-timing-eventlog-table {
|
|
202
|
+
width: 100%;
|
|
203
|
+
border-collapse: collapse;
|
|
204
|
+
font-size: 0.8em;
|
|
205
|
+
}
|
|
206
|
+
.ultravisor-timing-eventlog-table th {
|
|
207
|
+
text-align: left;
|
|
208
|
+
padding: 0.5em 0.75em;
|
|
209
|
+
background: #0d1b2a;
|
|
210
|
+
color: var(--uv-text-secondary);
|
|
211
|
+
border-bottom: 1px solid var(--uv-border-subtle);
|
|
212
|
+
font-weight: 600;
|
|
213
|
+
text-transform: uppercase;
|
|
214
|
+
font-size: 0.85em;
|
|
215
|
+
letter-spacing: 0.05em;
|
|
216
|
+
}
|
|
217
|
+
.ultravisor-timing-eventlog-table td {
|
|
218
|
+
padding: 0.4em 0.75em;
|
|
219
|
+
border-bottom: 1px solid var(--uv-bg-base);
|
|
220
|
+
color: var(--uv-text-secondary);
|
|
221
|
+
font-family: monospace;
|
|
222
|
+
}
|
|
223
|
+
.ultravisor-timing-eventlog-table tr:hover td {
|
|
224
|
+
background: #1a2744;
|
|
225
|
+
}
|
|
226
|
+
.ultravisor-timing-eventlog-v0 { color: var(--uv-text); }
|
|
227
|
+
.ultravisor-timing-eventlog-v1 { color: var(--uv-text-secondary); }
|
|
228
|
+
.ultravisor-timing-eventlog-v2 { color: #546e7a; }
|
|
172
229
|
`,
|
|
173
230
|
|
|
174
231
|
Templates:
|
|
@@ -185,6 +242,10 @@ const _ViewConfiguration =
|
|
|
185
242
|
<div id="Ultravisor-Timing-Detail"></div>
|
|
186
243
|
</div>
|
|
187
244
|
`
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
Hash: "Ultravisor-Timing-Row-Template",
|
|
248
|
+
Template: /*html*/`<div class="ultravisor-timing-row"><div class="ultravisor-timing-row-label" title="{~D:Record.LabelTitle~}" style="{~D:Record.LabelStyle~}">{~D:Record.Label~}</div><div class="ultravisor-timing-row-bar-container"><div class="ultravisor-timing-row-bar {~D:Record.BarClass~}" style="width: {~D:Record.WidthPercent~}%;{~D:Record.BarStyle~}">{~D:Record.BarText~}</div></div><div class="ultravisor-timing-row-duration">{~D:Record.Duration~}</div>{~D:Record.CountHTML~}</div>`
|
|
188
249
|
}
|
|
189
250
|
],
|
|
190
251
|
|
|
@@ -204,6 +265,9 @@ class UltravisorTimingView extends libPictView
|
|
|
204
265
|
constructor(pFable, pOptions, pServiceHash)
|
|
205
266
|
{
|
|
206
267
|
super(pFable, pOptions, pServiceHash);
|
|
268
|
+
|
|
269
|
+
this._currentVerbosity = 0;
|
|
270
|
+
this._currentManifest = null;
|
|
207
271
|
}
|
|
208
272
|
|
|
209
273
|
onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
|
|
@@ -235,45 +299,61 @@ class UltravisorTimingView extends libPictView
|
|
|
235
299
|
for (let i = tmpManifests.length - 1; i >= 0; i--)
|
|
236
300
|
{
|
|
237
301
|
let tmpManifest = tmpManifests[i];
|
|
238
|
-
let
|
|
239
|
-
let tmpLabel = (tmpManifest.
|
|
302
|
+
let tmpRunHash = tmpManifest.Hash || '';
|
|
303
|
+
let tmpLabel = (tmpManifest.OperationHash || tmpRunHash);
|
|
240
304
|
let tmpStatus = tmpManifest.Status || 'Unknown';
|
|
241
305
|
let tmpTime = tmpManifest.StartTime ? tmpManifest.StartTime.replace('T', ' ').replace(/\.\d+Z$/, '') : '';
|
|
242
|
-
tmpHTML += '<option value="' +
|
|
306
|
+
tmpHTML += '<option value="' + libTimingUtils.escapeHTML(tmpRunHash) + '">' + libTimingUtils.escapeHTML(tmpLabel) + ' [' + tmpStatus + '] ' + tmpTime + '</option>';
|
|
243
307
|
}
|
|
244
308
|
|
|
245
309
|
tmpHTML += '</select>';
|
|
246
310
|
this.pict.ContentAssignment.assignContent('#Ultravisor-Timing-Selector', tmpHTML);
|
|
247
311
|
}
|
|
248
312
|
|
|
249
|
-
onSelectManifest(
|
|
313
|
+
onSelectManifest(pRunHash)
|
|
250
314
|
{
|
|
251
|
-
if (!
|
|
315
|
+
if (!pRunHash)
|
|
252
316
|
{
|
|
253
317
|
this.pict.ContentAssignment.assignContent('#Ultravisor-Timing-Detail', '');
|
|
254
318
|
return;
|
|
255
319
|
}
|
|
256
320
|
|
|
257
|
-
this.pict.PictApplication.loadManifest(
|
|
321
|
+
this.pict.PictApplication.loadManifest(pRunHash,
|
|
258
322
|
function (pError, pManifest)
|
|
259
323
|
{
|
|
260
324
|
if (pError || !pManifest)
|
|
261
325
|
{
|
|
262
326
|
this.pict.ContentAssignment.assignContent('#Ultravisor-Timing-Detail',
|
|
263
|
-
'<div class="ultravisor-timing-card"><p style="color
|
|
327
|
+
'<div class="ultravisor-timing-card"><p style="color:var(--uv-error);">Error loading manifest details.</p></div>');
|
|
264
328
|
return;
|
|
265
329
|
}
|
|
266
330
|
|
|
331
|
+
this._currentManifest = pManifest;
|
|
332
|
+
this._currentVerbosity = 0;
|
|
267
333
|
this.renderTimingVisualization(pManifest);
|
|
268
334
|
}.bind(this));
|
|
269
335
|
}
|
|
270
336
|
|
|
271
337
|
renderTimingVisualization(pManifest)
|
|
272
338
|
{
|
|
273
|
-
|
|
339
|
+
// Convert TaskManifests object to an array for visualization
|
|
340
|
+
let tmpTaskResults = [];
|
|
341
|
+
if (pManifest.TaskManifests && typeof pManifest.TaskManifests === 'object')
|
|
342
|
+
{
|
|
343
|
+
let tmpKeys = Object.keys(pManifest.TaskManifests);
|
|
344
|
+
for (let k = 0; k < tmpKeys.length; k++)
|
|
345
|
+
{
|
|
346
|
+
let tmpEntry = pManifest.TaskManifests[tmpKeys[k]];
|
|
347
|
+
tmpEntry._NodeHash = tmpKeys[k];
|
|
348
|
+
tmpEntry._ComputedElapsedMs = libTimingUtils.computeTaskElapsedMs(tmpEntry);
|
|
349
|
+
tmpEntry._ComputedStatus = libTimingUtils.computeTaskStatus(tmpEntry);
|
|
350
|
+
tmpTaskResults.push(tmpEntry);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
274
354
|
let tmpOperationElapsedMs = pManifest.ElapsedMs || 0;
|
|
275
|
-
let tmpOperationElapsedFormatted =
|
|
276
|
-
let tmpAverageTaskMs =
|
|
355
|
+
let tmpOperationElapsedFormatted = libTimingUtils.formatMs(tmpOperationElapsedMs);
|
|
356
|
+
let tmpAverageTaskMs = 0;
|
|
277
357
|
let tmpStatus = (pManifest.Status || 'Unknown').toLowerCase();
|
|
278
358
|
let tmpStatusClass = (tmpStatus === 'complete' || tmpStatus === 'error' || tmpStatus === 'running') ? tmpStatus : '';
|
|
279
359
|
|
|
@@ -282,13 +362,13 @@ class UltravisorTimingView extends libPictView
|
|
|
282
362
|
{
|
|
283
363
|
for (let i = 0; i < tmpTaskResults.length; i++)
|
|
284
364
|
{
|
|
285
|
-
tmpOperationElapsedMs +=
|
|
365
|
+
tmpOperationElapsedMs += tmpTaskResults[i]._ComputedElapsedMs;
|
|
286
366
|
}
|
|
287
|
-
tmpOperationElapsedFormatted =
|
|
367
|
+
tmpOperationElapsedFormatted = libTimingUtils.formatMs(tmpOperationElapsedMs);
|
|
288
368
|
}
|
|
289
369
|
|
|
290
|
-
// Compute average
|
|
291
|
-
if (
|
|
370
|
+
// Compute average
|
|
371
|
+
if (tmpTaskResults.length > 0 && tmpOperationElapsedMs > 0)
|
|
292
372
|
{
|
|
293
373
|
tmpAverageTaskMs = tmpOperationElapsedMs / tmpTaskResults.length;
|
|
294
374
|
}
|
|
@@ -297,7 +377,7 @@ class UltravisorTimingView extends libPictView
|
|
|
297
377
|
let tmpMaxTaskMs = 0;
|
|
298
378
|
for (let i = 0; i < tmpTaskResults.length; i++)
|
|
299
379
|
{
|
|
300
|
-
let tmpMs = tmpTaskResults[i].
|
|
380
|
+
let tmpMs = tmpTaskResults[i]._ComputedElapsedMs;
|
|
301
381
|
if (tmpMs > tmpMaxTaskMs)
|
|
302
382
|
{
|
|
303
383
|
tmpMaxTaskMs = tmpMs;
|
|
@@ -308,18 +388,19 @@ class UltravisorTimingView extends libPictView
|
|
|
308
388
|
tmpMaxTaskMs = 1;
|
|
309
389
|
}
|
|
310
390
|
|
|
311
|
-
let tmpHTML = '
|
|
391
|
+
let tmpHTML = '';
|
|
312
392
|
|
|
313
|
-
// Summary
|
|
393
|
+
// ---- Summary Card ----
|
|
394
|
+
tmpHTML += '<div class="ultravisor-timing-card">';
|
|
314
395
|
tmpHTML += '<div class="ultravisor-timing-summary">';
|
|
315
|
-
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Operation</span><span class="ultravisor-timing-stat-value">' +
|
|
316
|
-
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Status</span><span class="ultravisor-timing-stat-value ' + tmpStatusClass + '">' +
|
|
317
|
-
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Total Time</span><span class="ultravisor-timing-stat-value">' +
|
|
396
|
+
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Operation</span><span class="ultravisor-timing-stat-value">' + libTimingUtils.escapeHTML(pManifest.OperationHash || '') + '</span></div>';
|
|
397
|
+
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Status</span><span class="ultravisor-timing-stat-value ' + tmpStatusClass + '">' + libTimingUtils.escapeHTML(pManifest.Status || 'Unknown') + '</span></div>';
|
|
398
|
+
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Total Time</span><span class="ultravisor-timing-stat-value">' + libTimingUtils.escapeHTML(tmpOperationElapsedFormatted) + '</span></div>';
|
|
318
399
|
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Tasks</span><span class="ultravisor-timing-stat-value">' + tmpTaskResults.length + '</span></div>';
|
|
319
|
-
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Avg per Task</span><span class="ultravisor-timing-stat-value">' +
|
|
400
|
+
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Avg per Task</span><span class="ultravisor-timing-stat-value">' + libTimingUtils.formatMs(tmpAverageTaskMs) + '</span></div>';
|
|
320
401
|
tmpHTML += '</div>';
|
|
321
402
|
|
|
322
|
-
// Timeline
|
|
403
|
+
// ---- Task Timeline ----
|
|
323
404
|
if (tmpTaskResults.length === 0)
|
|
324
405
|
{
|
|
325
406
|
tmpHTML += '<div class="ultravisor-timing-empty">No task results in this manifest.</div>';
|
|
@@ -332,9 +413,9 @@ class UltravisorTimingView extends libPictView
|
|
|
332
413
|
for (let i = 0; i < tmpTaskResults.length; i++)
|
|
333
414
|
{
|
|
334
415
|
let tmpResult = tmpTaskResults[i];
|
|
335
|
-
let tmpTaskMs = tmpResult.
|
|
336
|
-
let tmpTaskFormatted =
|
|
337
|
-
let tmpTaskStatus =
|
|
416
|
+
let tmpTaskMs = tmpResult._ComputedElapsedMs;
|
|
417
|
+
let tmpTaskFormatted = libTimingUtils.formatMs(tmpTaskMs);
|
|
418
|
+
let tmpTaskStatus = tmpResult._ComputedStatus.toLowerCase();
|
|
338
419
|
let tmpBarClass = 'other';
|
|
339
420
|
if (tmpTaskStatus === 'complete')
|
|
340
421
|
{
|
|
@@ -350,20 +431,22 @@ class UltravisorTimingView extends libPictView
|
|
|
350
431
|
}
|
|
351
432
|
|
|
352
433
|
let tmpWidthPercent = (tmpMaxTaskMs > 0) ? Math.max((tmpTaskMs / tmpMaxTaskMs) * 100, 1) : 1;
|
|
353
|
-
let
|
|
434
|
+
let tmpNodeHash = tmpResult._NodeHash || '';
|
|
435
|
+
let tmpDisplayName = tmpResult.TaskTypeName || tmpResult._NodeHash || 'Task ' + (i + 1);
|
|
354
436
|
|
|
355
|
-
|
|
356
|
-
tmpHTML += '<div class="ultravisor-timing-row-label" title="' + this.escapeHTML(tmpResult.GUIDTask || '') + '">' + this.escapeHTML(tmpResult.Name || tmpResult.GUIDTask || 'Task ' + (i + 1)) + '</div>';
|
|
357
|
-
tmpHTML += '<div class="ultravisor-timing-row-bar-container">';
|
|
358
|
-
tmpHTML += '<div class="ultravisor-timing-row-bar ' + tmpBarClass + '" style="width: ' + tmpWidthPercent.toFixed(1) + '%;">';
|
|
359
|
-
if (tmpWidthPercent > 20)
|
|
437
|
+
let tmpRowData =
|
|
360
438
|
{
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
439
|
+
Label: libTimingUtils.escapeHTML(tmpDisplayName),
|
|
440
|
+
LabelTitle: libTimingUtils.escapeHTML(tmpNodeHash),
|
|
441
|
+
LabelStyle: '',
|
|
442
|
+
BarClass: tmpBarClass,
|
|
443
|
+
BarStyle: '',
|
|
444
|
+
WidthPercent: tmpWidthPercent.toFixed(1),
|
|
445
|
+
BarText: (tmpWidthPercent > 20) ? '<span class="ultravisor-timing-row-bar-text">' + libTimingUtils.escapeHTML(tmpDisplayName) + '</span>' : '',
|
|
446
|
+
Duration: libTimingUtils.escapeHTML(tmpTaskFormatted),
|
|
447
|
+
CountHTML: ''
|
|
448
|
+
};
|
|
449
|
+
tmpHTML += this.pict.parseTemplateByHash('Ultravisor-Timing-Row-Template', tmpRowData);
|
|
367
450
|
}
|
|
368
451
|
|
|
369
452
|
// Time axis
|
|
@@ -373,7 +456,7 @@ class UltravisorTimingView extends libPictView
|
|
|
373
456
|
for (let t = 0; t <= tmpTickCount; t++)
|
|
374
457
|
{
|
|
375
458
|
let tmpTickMs = (tmpMaxTaskMs / tmpTickCount) * t;
|
|
376
|
-
tmpHTML += '<span class="ultravisor-timing-axis-tick">' +
|
|
459
|
+
tmpHTML += '<span class="ultravisor-timing-axis-tick">' + libTimingUtils.formatMs(tmpTickMs) + '</span>';
|
|
377
460
|
}
|
|
378
461
|
tmpHTML += '</div>';
|
|
379
462
|
tmpHTML += '<div class="ultravisor-timing-axis-spacer"></div>';
|
|
@@ -384,34 +467,213 @@ class UltravisorTimingView extends libPictView
|
|
|
384
467
|
|
|
385
468
|
tmpHTML += '</div>';
|
|
386
469
|
|
|
470
|
+
// ---- Category Histogram ----
|
|
471
|
+
if (pManifest.TimingSummary && pManifest.TimingSummary.ByCategory)
|
|
472
|
+
{
|
|
473
|
+
tmpHTML += this._renderCategoryHistogram(pManifest.TimingSummary.ByCategory);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// ---- Task Type Histogram ----
|
|
477
|
+
if (pManifest.TimingSummary && pManifest.TimingSummary.ByTaskType)
|
|
478
|
+
{
|
|
479
|
+
tmpHTML += this._renderTaskTypeHistogram(pManifest.TimingSummary.ByTaskType);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// ---- Event Log Panel ----
|
|
483
|
+
if (pManifest.EventLog && pManifest.EventLog.length > 0)
|
|
484
|
+
{
|
|
485
|
+
tmpHTML += this._renderEventLogPanel(pManifest);
|
|
486
|
+
}
|
|
487
|
+
|
|
387
488
|
this.pict.ContentAssignment.assignContent('#Ultravisor-Timing-Detail', tmpHTML);
|
|
388
489
|
}
|
|
389
490
|
|
|
390
|
-
|
|
491
|
+
_renderCategoryHistogram(pByCategory)
|
|
492
|
+
{
|
|
493
|
+
let tmpCategories = Object.keys(pByCategory);
|
|
494
|
+
if (tmpCategories.length === 0)
|
|
495
|
+
{
|
|
496
|
+
return '';
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// Sort by TotalMs descending
|
|
500
|
+
tmpCategories.sort(function (pA, pB)
|
|
501
|
+
{
|
|
502
|
+
return (pByCategory[pB].TotalMs || 0) - (pByCategory[pA].TotalMs || 0);
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
let tmpMaxMs = pByCategory[tmpCategories[0]].TotalMs || 1;
|
|
506
|
+
|
|
507
|
+
let tmpHTML = '<div class="ultravisor-timing-card">';
|
|
508
|
+
tmpHTML += '<div class="ultravisor-timing-chart">';
|
|
509
|
+
tmpHTML += '<div class="ultravisor-timing-chart-title">Time by Category</div>';
|
|
510
|
+
|
|
511
|
+
for (let i = 0; i < tmpCategories.length; i++)
|
|
512
|
+
{
|
|
513
|
+
let tmpCat = tmpCategories[i];
|
|
514
|
+
let tmpData = pByCategory[tmpCat];
|
|
515
|
+
let tmpMs = tmpData.TotalMs || 0;
|
|
516
|
+
let tmpWidthPercent = Math.max((tmpMs / tmpMaxMs) * 100, 1);
|
|
517
|
+
let tmpColors = libTimingUtils.CategoryColors[tmpCat] || libTimingUtils.CategoryColors['Uncategorized'];
|
|
518
|
+
|
|
519
|
+
let tmpRowData =
|
|
520
|
+
{
|
|
521
|
+
Label: libTimingUtils.escapeHTML(tmpCat),
|
|
522
|
+
LabelTitle: '',
|
|
523
|
+
LabelStyle: 'color:' + tmpColors.text + ';',
|
|
524
|
+
BarClass: '',
|
|
525
|
+
BarStyle: ' background: ' + tmpColors.bar + ';',
|
|
526
|
+
WidthPercent: tmpWidthPercent.toFixed(1),
|
|
527
|
+
BarText: (tmpWidthPercent > 15) ? '<span class="ultravisor-timing-row-bar-text">' + libTimingUtils.formatMs(tmpMs) + '</span>' : '',
|
|
528
|
+
Duration: libTimingUtils.formatMs(tmpMs),
|
|
529
|
+
CountHTML: '<div class="ultravisor-timing-row-count">' + tmpData.Count + 'x</div>'
|
|
530
|
+
};
|
|
531
|
+
tmpHTML += this.pict.parseTemplateByHash('Ultravisor-Timing-Row-Template', tmpRowData);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
tmpHTML += '</div>';
|
|
535
|
+
tmpHTML += '</div>';
|
|
536
|
+
return tmpHTML;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
_renderTaskTypeHistogram(pByTaskType)
|
|
391
540
|
{
|
|
392
|
-
|
|
541
|
+
let tmpTypes = Object.keys(pByTaskType);
|
|
542
|
+
if (tmpTypes.length === 0)
|
|
393
543
|
{
|
|
394
|
-
return '
|
|
544
|
+
return '';
|
|
395
545
|
}
|
|
396
|
-
|
|
546
|
+
|
|
547
|
+
// Sort by TotalMs descending
|
|
548
|
+
tmpTypes.sort(function (pA, pB)
|
|
549
|
+
{
|
|
550
|
+
return (pByTaskType[pB].TotalMs || 0) - (pByTaskType[pA].TotalMs || 0);
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
let tmpMaxMs = pByTaskType[tmpTypes[0]].TotalMs || 1;
|
|
554
|
+
|
|
555
|
+
let tmpHTML = '<div class="ultravisor-timing-card">';
|
|
556
|
+
tmpHTML += '<div class="ultravisor-timing-chart">';
|
|
557
|
+
tmpHTML += '<div class="ultravisor-timing-chart-title">Time by Task Type</div>';
|
|
558
|
+
|
|
559
|
+
for (let i = 0; i < tmpTypes.length; i++)
|
|
397
560
|
{
|
|
398
|
-
|
|
561
|
+
let tmpType = tmpTypes[i];
|
|
562
|
+
let tmpData = pByTaskType[tmpType];
|
|
563
|
+
let tmpMs = tmpData.TotalMs || 0;
|
|
564
|
+
let tmpWidthPercent = Math.max((tmpMs / tmpMaxMs) * 100, 1);
|
|
565
|
+
let tmpCategory = tmpData.Category || 'Uncategorized';
|
|
566
|
+
let tmpColors = libTimingUtils.CategoryColors[tmpCategory] || libTimingUtils.CategoryColors['Uncategorized'];
|
|
567
|
+
let tmpDisplayName = tmpData.Name || tmpType;
|
|
568
|
+
|
|
569
|
+
let tmpRowData =
|
|
570
|
+
{
|
|
571
|
+
Label: libTimingUtils.escapeHTML(tmpDisplayName),
|
|
572
|
+
LabelTitle: libTimingUtils.escapeHTML(tmpType),
|
|
573
|
+
LabelStyle: '',
|
|
574
|
+
BarClass: '',
|
|
575
|
+
BarStyle: ' background: ' + tmpColors.bar + ';',
|
|
576
|
+
WidthPercent: tmpWidthPercent.toFixed(1),
|
|
577
|
+
BarText: (tmpWidthPercent > 15) ? '<span class="ultravisor-timing-row-bar-text">' + libTimingUtils.formatMs(tmpMs) + '</span>' : '',
|
|
578
|
+
Duration: libTimingUtils.formatMs(tmpMs),
|
|
579
|
+
CountHTML: '<div class="ultravisor-timing-row-count">' + tmpData.Count + 'x</div>'
|
|
580
|
+
};
|
|
581
|
+
tmpHTML += this.pict.parseTemplateByHash('Ultravisor-Timing-Row-Template', tmpRowData);
|
|
399
582
|
}
|
|
400
|
-
|
|
583
|
+
|
|
584
|
+
tmpHTML += '</div>';
|
|
585
|
+
tmpHTML += '</div>';
|
|
586
|
+
return tmpHTML;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
_renderEventLogPanel(pManifest)
|
|
590
|
+
{
|
|
591
|
+
let tmpViewRef = "_Pict.views['Ultravisor-TimingView']";
|
|
592
|
+
|
|
593
|
+
let tmpHTML = '<div class="ultravisor-timing-card">';
|
|
594
|
+
tmpHTML += '<div class="ultravisor-timing-chart">';
|
|
595
|
+
tmpHTML += '<div class="ultravisor-timing-chart-title">Event Log</div>';
|
|
596
|
+
|
|
597
|
+
// Verbosity toggle buttons
|
|
598
|
+
tmpHTML += '<div class="ultravisor-timing-verbosity-controls">';
|
|
599
|
+
tmpHTML += '<button class="ultravisor-timing-verbosity-btn' + (this._currentVerbosity === 0 ? ' active' : '') + '" onclick="' + tmpViewRef + '.setVerbosity(0)">Normal</button>';
|
|
600
|
+
tmpHTML += '<button class="ultravisor-timing-verbosity-btn' + (this._currentVerbosity === 1 ? ' active' : '') + '" onclick="' + tmpViewRef + '.setVerbosity(1)">Verbose</button>';
|
|
601
|
+
tmpHTML += '<button class="ultravisor-timing-verbosity-btn' + (this._currentVerbosity === 2 ? ' active' : '') + '" onclick="' + tmpViewRef + '.setVerbosity(2)">Ultra-verbose</button>';
|
|
602
|
+
tmpHTML += '</div>';
|
|
603
|
+
|
|
604
|
+
tmpHTML += '<div id="Ultravisor-Timing-EventLog-Body">';
|
|
605
|
+
tmpHTML += this._renderEventLogTable(pManifest.EventLog, pManifest.StartTime);
|
|
606
|
+
tmpHTML += '</div>';
|
|
607
|
+
|
|
608
|
+
tmpHTML += '</div>';
|
|
609
|
+
tmpHTML += '</div>';
|
|
610
|
+
return tmpHTML;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
_renderEventLogTable(pEventLog, pOperationStartTime)
|
|
614
|
+
{
|
|
615
|
+
let tmpStartMs = pOperationStartTime ? new Date(pOperationStartTime).getTime() : 0;
|
|
616
|
+
let tmpMaxVerbosity = this._currentVerbosity;
|
|
617
|
+
|
|
618
|
+
let tmpHTML = '<table class="ultravisor-timing-eventlog-table">';
|
|
619
|
+
tmpHTML += '<thead><tr><th>Time</th><th>Node</th><th>Event</th><th>Message</th></tr></thead>';
|
|
620
|
+
tmpHTML += '<tbody>';
|
|
621
|
+
|
|
622
|
+
let tmpVisibleCount = 0;
|
|
623
|
+
|
|
624
|
+
for (let i = 0; i < pEventLog.length; i++)
|
|
401
625
|
{
|
|
402
|
-
let
|
|
403
|
-
|
|
404
|
-
|
|
626
|
+
let tmpEvent = pEventLog[i];
|
|
627
|
+
|
|
628
|
+
if (tmpEvent.Verbosity > tmpMaxVerbosity)
|
|
629
|
+
{
|
|
630
|
+
continue;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
tmpVisibleCount++;
|
|
634
|
+
let tmpRelativeMs = (tmpEvent.TimestampMs && tmpStartMs) ? (tmpEvent.TimestampMs - tmpStartMs) : 0;
|
|
635
|
+
let tmpVerbClass = 'ultravisor-timing-eventlog-v' + (tmpEvent.Verbosity || 0);
|
|
636
|
+
|
|
637
|
+
tmpHTML += '<tr class="' + tmpVerbClass + '">';
|
|
638
|
+
tmpHTML += '<td>+' + libTimingUtils.formatMs(tmpRelativeMs) + '</td>';
|
|
639
|
+
tmpHTML += '<td>' + libTimingUtils.escapeHTML(tmpEvent.NodeHash || '-') + '</td>';
|
|
640
|
+
tmpHTML += '<td>' + libTimingUtils.escapeHTML(tmpEvent.EventName || '') + '</td>';
|
|
641
|
+
tmpHTML += '<td>' + libTimingUtils.escapeHTML(tmpEvent.Message || '') + '</td>';
|
|
642
|
+
tmpHTML += '</tr>';
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
if (tmpVisibleCount === 0)
|
|
646
|
+
{
|
|
647
|
+
tmpHTML += '<tr><td colspan="4" style="text-align:center; color:var(--uv-text-tertiary); font-style:italic;">No events at this verbosity level.</td></tr>';
|
|
405
648
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
return
|
|
649
|
+
|
|
650
|
+
tmpHTML += '</tbody></table>';
|
|
651
|
+
return tmpHTML;
|
|
409
652
|
}
|
|
410
653
|
|
|
411
|
-
|
|
654
|
+
setVerbosity(pLevel)
|
|
412
655
|
{
|
|
413
|
-
|
|
414
|
-
|
|
656
|
+
this._currentVerbosity = pLevel;
|
|
657
|
+
|
|
658
|
+
if (this._currentManifest && this._currentManifest.EventLog)
|
|
659
|
+
{
|
|
660
|
+
// Re-render the event log table only
|
|
661
|
+
let tmpTableHTML = this._renderEventLogTable(this._currentManifest.EventLog, this._currentManifest.StartTime);
|
|
662
|
+
this.pict.ContentAssignment.assignContent('#Ultravisor-Timing-EventLog-Body', tmpTableHTML);
|
|
663
|
+
|
|
664
|
+
// Update button active states
|
|
665
|
+
let tmpViewRef = "_Pict.views['Ultravisor-TimingView']";
|
|
666
|
+
let tmpBtnHTML = '';
|
|
667
|
+
tmpBtnHTML += '<button class="ultravisor-timing-verbosity-btn' + (pLevel === 0 ? ' active' : '') + '" onclick="' + tmpViewRef + '.setVerbosity(0)">Normal</button>';
|
|
668
|
+
tmpBtnHTML += '<button class="ultravisor-timing-verbosity-btn' + (pLevel === 1 ? ' active' : '') + '" onclick="' + tmpViewRef + '.setVerbosity(1)">Verbose</button>';
|
|
669
|
+
tmpBtnHTML += '<button class="ultravisor-timing-verbosity-btn' + (pLevel === 2 ? ' active' : '') + '" onclick="' + tmpViewRef + '.setVerbosity(2)">Ultra-verbose</button>';
|
|
670
|
+
|
|
671
|
+
let tmpControlsEl = document.querySelector('.ultravisor-timing-verbosity-controls');
|
|
672
|
+
if (tmpControlsEl)
|
|
673
|
+
{
|
|
674
|
+
tmpControlsEl.innerHTML = tmpBtnHTML;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
415
677
|
}
|
|
416
678
|
}
|
|
417
679
|
|