omni-viewer-core 0.22.0 → 0.23.0
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/README.md +251 -5
- package/THIRD_PARTY_NOTICES.md +23 -0
- package/dist/i18n/catalog.en.js +298 -0
- package/dist/i18n/catalog.ja.js +298 -0
- package/dist/i18n/catalog.ko.js +298 -0
- package/dist/i18n/catalog.zh-cn.js +298 -0
- package/dist/i18n/catalog.zh-tw.js +185 -0
- package/dist/parsers/dicom/index.d.ts +6 -0
- package/dist/parsers/dicom/index.js +335 -0
- package/dist/parsers/dicom/model.d.ts +67 -0
- package/dist/parsers/dicom/model.js +1 -0
- package/dist/parsers/dicom/pixels.d.ts +9 -0
- package/dist/parsers/dicom/pixels.js +82 -0
- package/dist/parsers/eml/index.d.ts +37 -0
- package/dist/parsers/eml/index.js +278 -0
- package/dist/parsers/junit/index.d.ts +49 -0
- package/dist/parsers/junit/index.js +841 -0
- package/dist/parsers/junit/model.d.ts +141 -0
- package/dist/parsers/junit/model.js +8 -0
- package/dist/parsers/junit/sniff.d.ts +7 -0
- package/dist/parsers/junit/sniff.js +86 -0
- package/dist/parsers/mcap/errors.d.ts +5 -0
- package/dist/parsers/mcap/errors.js +5 -0
- package/dist/parsers/mcap/index.d.ts +95 -0
- package/dist/parsers/mcap/index.js +321 -0
- package/dist/parsers/mcap/self-loading.d.ts +6 -0
- package/dist/parsers/mcap/self-loading.js +21 -0
- package/dist/parsers/mcap/zstd.d.ts +8 -0
- package/dist/parsers/mcap/zstd.js +102 -0
- package/dist/parsers/mesh/index.d.ts +28 -0
- package/dist/parsers/mesh/index.js +351 -0
- package/dist/parsers/mesh/validation.d.ts +11 -0
- package/dist/parsers/mesh/validation.js +215 -0
- package/dist/parsers/openapi/index.d.ts +24 -0
- package/dist/parsers/openapi/index.js +319 -0
- package/dist/parsers/openapi/model.d.ts +57 -0
- package/dist/parsers/openapi/model.js +1 -0
- package/dist/parsers/openapi/nodes.d.ts +19 -0
- package/dist/parsers/openapi/nodes.js +214 -0
- package/dist/parsers/openapi/self-loading.d.ts +5 -0
- package/dist/parsers/openapi/self-loading.js +35 -0
- package/dist/parsers/openapi/sniff.d.ts +6 -0
- package/dist/parsers/openapi/sniff.js +136 -0
- package/dist/parsers/text/index.d.ts +17 -0
- package/dist/parsers/text/index.js +68 -0
- package/dist/parsers/xml/model.d.ts +3 -0
- package/dist/parsers/xml/parse.js +5 -1
- package/dist/parsers/yaml/index.js +3 -2
- package/dist/parsers/yaml/model.d.ts +2 -1
- package/dist/parsers/yaml/self-loading.js +2 -2
- package/dist/registry/index.d.ts +19 -4
- package/dist/registry/index.js +88 -9
- package/dist/registry/sniff.d.ts +6 -1
- package/dist/registry/sniff.js +26 -1
- package/dist/styles/dicom.css +14 -0
- package/dist/styles/eml.css +19 -0
- package/dist/styles/junit.css +96 -0
- package/dist/styles/mcap.css +25 -0
- package/dist/styles/mesh.css +15 -0
- package/dist/styles/openapi.css +38 -0
- package/dist/styles/text.css +14 -0
- package/dist/viewers/dicom/index.d.ts +18 -0
- package/dist/viewers/dicom/index.js +222 -0
- package/dist/viewers/dicom/styles.d.ts +1 -0
- package/dist/viewers/dicom/styles.js +15 -0
- package/dist/viewers/eml/index.d.ts +19 -0
- package/dist/viewers/eml/index.js +219 -0
- package/dist/viewers/eml/styles.d.ts +1 -0
- package/dist/viewers/eml/styles.js +20 -0
- package/dist/viewers/html/index.d.ts +1 -1
- package/dist/viewers/html/index.js +7 -2
- package/dist/viewers/junit/index.d.ts +31 -0
- package/dist/viewers/junit/index.js +840 -0
- package/dist/viewers/junit/styles.d.ts +1 -0
- package/dist/viewers/junit/styles.js +101 -0
- package/dist/viewers/mcap/index.d.ts +30 -0
- package/dist/viewers/mcap/index.js +281 -0
- package/dist/viewers/mcap/self-loading.d.ts +4 -0
- package/dist/viewers/mcap/self-loading.js +16 -0
- package/dist/viewers/mcap/styles.d.ts +1 -0
- package/dist/viewers/mcap/styles.js +26 -0
- package/dist/viewers/mesh/async.d.ts +2 -0
- package/dist/viewers/mesh/async.js +19 -0
- package/dist/viewers/mesh/index.d.ts +39 -0
- package/dist/viewers/mesh/index.js +462 -0
- package/dist/viewers/mesh/self-loading.d.ts +6 -0
- package/dist/viewers/mesh/self-loading.js +28 -0
- package/dist/viewers/mesh/styles.d.ts +2 -0
- package/dist/viewers/mesh/styles.js +17 -0
- package/dist/viewers/openapi/controller.d.ts +20 -0
- package/dist/viewers/openapi/controller.js +74 -0
- package/dist/viewers/openapi/index.d.ts +25 -0
- package/dist/viewers/openapi/index.js +556 -0
- package/dist/viewers/openapi/self-loading.d.ts +5 -0
- package/dist/viewers/openapi/self-loading.js +13 -0
- package/dist/viewers/openapi/styles.d.ts +2 -0
- package/dist/viewers/openapi/styles.js +40 -0
- package/dist/viewers/text/index.d.ts +19 -0
- package/dist/viewers/text/index.js +91 -0
- package/dist/viewers/text/styles.d.ts +1 -0
- package/dist/viewers/text/styles.js +15 -0
- package/package.json +106 -10
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ models, viewers mount into a DOM element, and everything host-specific
|
|
|
12
12
|
|
|
13
13
|
## Supported formats
|
|
14
14
|
|
|
15
|
-
- **Documents** — PDF, Word (DOCX and legacy DOC), HWP, PowerPoint (PPTX and
|
|
15
|
+
- **Documents** — Plain text (.txt), PDF, Word (DOCX and legacy DOC), HWP, PowerPoint (PPTX and
|
|
16
16
|
legacy PPT), HTML, Markdown, Jupyter Notebook (.ipynb), EPUB e-books (2 and 3),
|
|
17
17
|
LaTeX (structure and math preview, not typesetting)
|
|
18
18
|
- **Data & spreadsheets** — Excel, CSV/TSV, JSON, JSONL/NDJSON, YAML, TOML, XML,
|
|
@@ -20,11 +20,16 @@ models, viewers mount into a DOM element, and everything host-specific
|
|
|
20
20
|
Keras (.keras and legacy .h5), Core ML (.mlmodel and .mlpackage),
|
|
21
21
|
OpenVINO IR (.xml + .bin), PyTorch Export (.pt2), ExecuTorch (.pte), Protocol
|
|
22
22
|
Buffers, ReqIF, SQLite
|
|
23
|
-
- **
|
|
23
|
+
- **Email, web & network** — EML email messages, HAR (HTTP Archive) request logs,
|
|
24
|
+
OpenAPI / Swagger API documents (JSON/YAML)
|
|
25
|
+
- **Developer tooling** — JUnit XML test reports (Gradle, Maven Surefire,
|
|
26
|
+
pytest, vitest/Jest, Jenkins and other JUnit-format writers)
|
|
27
|
+
- **Medical imaging** — DICOM (.dcm/.dicom), native grayscale/RGB image preview,
|
|
28
|
+
multi-frame navigation, windowing and metadata inspection
|
|
24
29
|
- **Media & graphics** — audio (waveform/spectrogram), video, images,
|
|
25
|
-
Photoshop PSD, fonts (TTF/OTF/WOFF)
|
|
30
|
+
Photoshop PSD, fonts (TTF/OTF/WOFF), 3D meshes (GLB/glTF/STL/OBJ)
|
|
26
31
|
- **Engineering & automotive** — CAN DBC, AUTOSAR ARXML, ASAM A2L, Vector
|
|
27
|
-
ASC/BLF logs, ASAM MDF 4 (MF4), PCAP/PCAPNG, ROS bag, STEP (STP)
|
|
32
|
+
ASC/BLF logs, ASAM MDF 4 (MF4), PCAP/PCAPNG, ROS bag, MCAP (.mcap), STEP (STP)
|
|
28
33
|
- **Diagrams & GIS** — Mermaid, PlantUML, ESRI Shapefile, GeoJSON
|
|
29
34
|
- **Archives** — ZIP-family listing and safe entry preview
|
|
30
35
|
|
|
@@ -34,6 +39,50 @@ navigation removed or blocked; inline styles and embedded data images remain.
|
|
|
34
39
|
Files over 8 MiB show a bounded source preview. Very dense markup opens in
|
|
35
40
|
source view to keep parsing responsive.
|
|
36
41
|
|
|
42
|
+
### Plain text (.txt)
|
|
43
|
+
|
|
44
|
+
`omni-viewer-core/viewers/text` provides a dependency-free, read-only text
|
|
45
|
+
viewer. Whitespace, tabs and line endings are preserved; HTML and Markdown
|
|
46
|
+
remain literal text. Soft line wrapping can be toggled without changing the
|
|
47
|
+
content. UTF-8 is the default; UTF-8 and UTF-16 LE/BE BOMs are recognized.
|
|
48
|
+
For BOM-less UTF-16, pass `parse: { encoding: 'utf-16le' }` (or `'utf-16be'`).
|
|
49
|
+
Legacy encodings such as CP949 are not automatically detected. Malformed
|
|
50
|
+
Unicode bytes are displayed as replacement characters with a visible warning;
|
|
51
|
+
UTF-32 BOMs are rejected.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { mountTextViewer } from 'omni-viewer-core/viewers/text';
|
|
55
|
+
|
|
56
|
+
const handle = await mountTextViewer(
|
|
57
|
+
{ fileName: 'notes.txt', data: bytes }, container, hostContext
|
|
58
|
+
);
|
|
59
|
+
// On file switch or tab close:
|
|
60
|
+
handle.dispose();
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The DOM-free parser is available at `omni-viewer-core/parsers/text` as
|
|
64
|
+
`parseText(bytes, options)`. The default input limit is 256 MiB and the decoded
|
|
65
|
+
preview budget is 8 MiB (excluding the BOM); larger previews are visibly marked
|
|
66
|
+
as partial. Override them through `limits.maxInputBytes` / `maxPreviewBytes`
|
|
67
|
+
(under `parse.limits` for the viewer). Incomplete characters at a preview
|
|
68
|
+
boundary are omitted without an encoding warning. Decoding limits are
|
|
69
|
+
cooperative; hosts still own file loading and hard CPU/memory bounds.
|
|
70
|
+
Scoped hosts load `omni-viewer-core/styles/text.css`; shadow mode injects it.
|
|
71
|
+
|
|
72
|
+
The registry returns `viewerId: 'text'` for `.txt` (including uppercase `.TXT`).
|
|
73
|
+
Hosts must register that extension and explicitly map `text` to
|
|
74
|
+
`mountTextViewer`; the registry does not load viewers. Other extensions and
|
|
75
|
+
extensionless text retain their existing detection behavior.
|
|
76
|
+
|
|
77
|
+
### DICOM (.dcm/.dicom)
|
|
78
|
+
|
|
79
|
+
`omni-viewer-core/viewers/dicom` provides a dependency-free native 8/16-bit DICOM
|
|
80
|
+
preview with frame navigation, window center/width, inversion, zoom, and a
|
|
81
|
+
searchable metadata table. Implicit/explicit VR little endian and explicit VR
|
|
82
|
+
big endian are supported. Compressed images keep metadata available and report
|
|
83
|
+
that preview is unavailable. See [DICOM support and limits](examples/dicom/SUPPORT.md)
|
|
84
|
+
and the [offline synthetic example](examples/dicom/README.md).
|
|
85
|
+
|
|
37
86
|
## Install
|
|
38
87
|
|
|
39
88
|
```sh
|
|
@@ -74,6 +123,122 @@ Viewers follow the same pattern — a `mount*Viewer(input, container, ctx,
|
|
|
74
123
|
deps)` entry per format, plus `self-loading` variants that dynamically import
|
|
75
124
|
their own dependencies for hosts that don't want to wire them manually.
|
|
76
125
|
|
|
126
|
+
### OpenAPI / Swagger (JSON / YAML)
|
|
127
|
+
|
|
128
|
+
Open Swagger 2.0 and OpenAPI 3.0–3.2 specifications with searchable API
|
|
129
|
+
documentation, HTTP method/tag filters, parameter and request/response schemas,
|
|
130
|
+
examples, authentication definitions and an original-source tab.
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { mountSelfLoadingOpenApiViewer } from 'omni-viewer-core/viewers/openapi/self-loading';
|
|
134
|
+
|
|
135
|
+
const handle = await mountSelfLoadingOpenApiViewer(
|
|
136
|
+
{ fileName: 'openapi.yaml', data: bytes }, container, hostContext
|
|
137
|
+
);
|
|
138
|
+
handle.dispose();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
JSON needs no external library. YAML uses the optional `yaml` 2.8.3 peer;
|
|
142
|
+
base parser/viewer entries accept injected `yamlDeps`, and the opt-in
|
|
143
|
+
`/self-loading` entries load it for YAML. The registry refines generic
|
|
144
|
+
JSON/YAML to OpenAPI when file content matches; ordinary files retain their
|
|
145
|
+
existing viewers. Pass complete text plus `{ yamlDeps }` as `detectViewer`'s
|
|
146
|
+
sixth argument for strict YAML detection. Without it, conservative block YAML
|
|
147
|
+
signatures are recognized and validated when mounted.
|
|
148
|
+
|
|
149
|
+
Local references, Swagger definitions and parameter inheritance are supported.
|
|
150
|
+
The viewer runs offline and renders descriptions as text. Exports include
|
|
151
|
+
`parsers/openapi`, `viewers/openapi`, their `/self-loading` entries and
|
|
152
|
+
`styles/openapi.css`. See the [viewer contract](docs/viewers/openapi.md) and
|
|
153
|
+
[runnable examples](examples/openapi/README.md) for integration and limits.
|
|
154
|
+
|
|
155
|
+
### 3D meshes (GLB / glTF / STL / OBJ)
|
|
156
|
+
|
|
157
|
+
Install `three` (`^0.180.0`) and, for TypeScript projects, `@types/three`
|
|
158
|
+
(`^0.180.0`). The viewer provides orbit/pan/zoom, fit to view, wireframe,
|
|
159
|
+
grid/axes, mesh statistics, glTF materials and animation playback.
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import { mountSelfLoadingMeshViewer } from 'omni-viewer-core/viewers/mesh/self-loading';
|
|
163
|
+
|
|
164
|
+
const handle = await mountSelfLoadingMeshViewer(
|
|
165
|
+
{ fileName: 'model.glb', data: bytes }, container, hostContext
|
|
166
|
+
);
|
|
167
|
+
// On file switch or tab close:
|
|
168
|
+
handle.dispose();
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
For injected runtimes, use `mountMeshViewer(input, container, ctx, deps, options)`
|
|
172
|
+
from `viewers/mesh`; `loadMeshViewerDeps()` supplies the standard Three.js deps.
|
|
173
|
+
`parsers/mesh` offers DOM-free `parseMesh(bytes, { fileName, limits })`
|
|
174
|
+
preflight without loading Three.js. It validates structure, coordinates, resource
|
|
175
|
+
paths and budgets; scene decoding happens when mounted.
|
|
176
|
+
|
|
177
|
+
Self-contained GLB and embedded glTF need no asset service. For `.gltf` with
|
|
178
|
+
external `.bin` or textures, provide `ctx.documentAssets.resolve(relativePath)`;
|
|
179
|
+
each returned asset's `dispose()` is called when the viewer closes. Input URLs,
|
|
180
|
+
absolute paths and parent traversal are rejected; the core never resolves them
|
|
181
|
+
against the page URL. Hosts must cap external asset sizes as well as the main
|
|
182
|
+
input. OBJ geometry, UVs and normals are supported; MTL libraries use default
|
|
183
|
+
materials with a warning. OBJ line and point primitives are omitted with a
|
|
184
|
+
warning. Compressed glTF requires host-provided decoders via
|
|
185
|
+
`deps.configureGltfLoader`; the core never downloads them. Rendering requires
|
|
186
|
+
WebGL 2. Scoped hosts should load `styles/mesh.css`; shadow mode injects it.
|
|
187
|
+
|
|
188
|
+
glTF preflight also budgets generated accessors, animation arrays, skeletons,
|
|
189
|
+
instancing and morph storage. Generated GPU storage uses conservative estimates
|
|
190
|
+
to cover device-dependent padding before rendering.
|
|
191
|
+
|
|
192
|
+
Run `npm run build`, serve the repo root, and open `examples/mesh/` for a
|
|
193
|
+
standalone example with sample files in all four formats and local file loading.
|
|
194
|
+
|
|
195
|
+
### MCAP (.mcap)
|
|
196
|
+
|
|
197
|
+
Inspect topics/channels, schemas, sampled messages, metadata, attachments and
|
|
198
|
+
chunks in MCAP v0 recordings. The viewer includes topic filtering, search,
|
|
199
|
+
pagination, text/hex payload inspection and JSON copy. JSON payloads are
|
|
200
|
+
formatted when complete; CDR, Protobuf and other binary payloads are shown as
|
|
201
|
+
raw bytes. Attachments are listed without extracting or executing their data.
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
import { mountSelfLoadingMcapViewer } from 'omni-viewer-core/viewers/mcap/self-loading';
|
|
205
|
+
|
|
206
|
+
const handle = await mountSelfLoadingMcapViewer(
|
|
207
|
+
{ fileName: 'robot.mcap', data: bytes }, container, ctx,
|
|
208
|
+
{ parse: { previewMessages: 5_000 } }
|
|
209
|
+
);
|
|
210
|
+
// On close: handle.dispose();
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Install the existing optional peers `lz4js` and `fzstd` to read compressed
|
|
214
|
+
chunks with the self-loading entry. Uncompressed recordings need no peers.
|
|
215
|
+
The base `parsers/mcap` and `viewers/mcap` entries import no runtime peers:
|
|
216
|
+
`parseMcap(bytes, { decompressLz4?, decompressZstd? }, parseOptions)` and
|
|
217
|
+
`mountMcapViewer(input, container, ctx, deps?, mountOptions?)` accept injected
|
|
218
|
+
bounded decoders (the optional third argument limits decoder history bytes).
|
|
219
|
+
Injected decoders may throw `McapDecompressionLimitError` to report resource
|
|
220
|
+
limits separately from malformed input.
|
|
221
|
+
`parsers/mcap/self-loading` exports `parseSelfLoadingMcap`
|
|
222
|
+
and `loadMcapDeps`. Missing/unknown codecs leave a partial document with any
|
|
223
|
+
available summary statistics and schemas. Incomplete scans display lower-bound
|
|
224
|
+
counts when exact summary counts are unavailable.
|
|
225
|
+
|
|
226
|
+
Defaults: 256 MiB input and cumulative chunk bytes, 1,000,000 records/map entries,
|
|
227
|
+
5,000 retained messages, 4 KiB per payload/schema preview and an 8 MiB cumulative
|
|
228
|
+
preview budget. Structural encoding identifiers are read independently of the
|
|
229
|
+
preview budget (up to 16 KiB). Zstd frame content sizes and history windows are
|
|
230
|
+
checked before decoding; history uses the configured chunk byte limit.
|
|
231
|
+
Search/copy operate on retained samples; totals include every
|
|
232
|
+
scanned message. Uint64 values remain decimal strings and timestamps display
|
|
233
|
+
exact seconds relative to the recording's epoch. Chunk, data-section and summary
|
|
234
|
+
CRCs are checked when present; attachment payload CRCs are not checked. Limits
|
|
235
|
+
are cooperative; hosts can use a Worker for hard CPU/memory bounds. The viewer
|
|
236
|
+
supports shadow/scoped isolation and `styles/mcap.css`. Detection recognizes
|
|
237
|
+
the `.mcap` extension and binary magic, including extensionless recordings.
|
|
238
|
+
Host adapters must add `mcap` to their explicit viewer import maps.
|
|
239
|
+
|
|
240
|
+
The binary reader follows the [MCAP format specification](https://mcap.dev/spec).
|
|
241
|
+
|
|
77
242
|
### Fonts (TTF / OTF / WOFF)
|
|
78
243
|
|
|
79
244
|
Preview local fonts with editable sample text, size and variable axis controls,
|
|
@@ -489,6 +654,46 @@ returns `partial` with diagnostics. Invalid JSON and unsupported major versions
|
|
|
489
654
|
return typed failures. See [viewer details](examples/notebook/README.md) and the
|
|
490
655
|
[sample notebook](examples/notebook/analysis.ipynb).
|
|
491
656
|
|
|
657
|
+
### EML email (.eml)
|
|
658
|
+
|
|
659
|
+
The EML viewer displays decoded subjects, sender/recipient fields, dates,
|
|
660
|
+
plain-text and HTML bodies, all message headers, a bounded raw-source preview,
|
|
661
|
+
and attachments. It handles nested MIME messages, Base64/quoted-printable,
|
|
662
|
+
encoded header words, legacy body charsets, and extended attachment filenames.
|
|
663
|
+
Attached messages remain downloadable `.eml` files rather than becoming the
|
|
664
|
+
parent message's body. Extensionless messages are detected conservatively.
|
|
665
|
+
|
|
666
|
+
```ts
|
|
667
|
+
import { mountEmlViewer } from 'omni-viewer-core/viewers/eml';
|
|
668
|
+
import { createCatalogI18n } from 'omni-viewer-core/i18n';
|
|
669
|
+
|
|
670
|
+
const handle = await mountEmlViewer(
|
|
671
|
+
{ fileName: file.name, data: new Uint8Array(await file.arrayBuffer()) },
|
|
672
|
+
container,
|
|
673
|
+
{
|
|
674
|
+
assets: { resolveAssetUrl: async path => path },
|
|
675
|
+
i18n: createCatalogI18n('ko'),
|
|
676
|
+
logger: { log: (level, message) => console.log(level, message) },
|
|
677
|
+
// Optional: save: { saveFile: async (name, bytes, mimeType) => … },
|
|
678
|
+
// Optional: clipboard: { writeText: text => navigator.clipboard.writeText(text) }
|
|
679
|
+
}
|
|
680
|
+
);
|
|
681
|
+
// On file change / unmount:
|
|
682
|
+
handle.dispose();
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
HTML runs in an opaque sandbox with scripts, navigation, forms, and remote
|
|
686
|
+
resources blocked. Embedded `cid:` raster images render locally. Attachment
|
|
687
|
+
filenames are sanitized; saving goes through the optional host `save` service.
|
|
688
|
+
Copy/save controls are disabled when their host service is absent. No MIME
|
|
689
|
+
dependency is required. Default parsing limits are 32 MiB input/decoded data,
|
|
690
|
+
1,000 MIME parts, 32 nesting levels, and 4 MiB per body preview. Limits can be
|
|
691
|
+
configured through `parseEml(bytes, options)` from `parsers/eml`.
|
|
692
|
+
|
|
693
|
+
The default mount uses Shadow DOM. Scoped mounting requires
|
|
694
|
+
`omni-viewer-core/styles/eml.css`. Run `npm run build`, serve the repository
|
|
695
|
+
root, and open `examples/eml/` for sample messages and a local file picker.
|
|
696
|
+
|
|
492
697
|
### HAR network logs (.har)
|
|
493
698
|
|
|
494
699
|
A `.har` file is the HTTP Archive a browser's network panel (or curl, Charles,
|
|
@@ -535,6 +740,46 @@ metadata get their own tabs. Routing is by the `.har` extension; an
|
|
|
535
740
|
extensionless archive is recognized by content — a `log` object holding an
|
|
536
741
|
`entries` array — and claimed before the generic JSON viewer.
|
|
537
742
|
|
|
743
|
+
### JUnit XML test reports
|
|
744
|
+
|
|
745
|
+
A JUnit XML report is what nearly every test runner writes for CI: Gradle's
|
|
746
|
+
`build/test-results/**/TEST-*.xml`, Maven Surefire, `pytest --junitxml`,
|
|
747
|
+
vitest/Jest JUnit reporters, Go and Android tooling. It is an ordinary `.xml`,
|
|
748
|
+
so the generic XML viewer keeps the extension and `detectViewer` routes a file
|
|
749
|
+
to `junit` only when the supplied text sample has a `<testsuites>` root, or a
|
|
750
|
+
`<testsuite>` root carrying counts or a JUnit child element:
|
|
751
|
+
|
|
752
|
+
```ts
|
|
753
|
+
import { detectViewer } from 'omni-viewer-core/registry';
|
|
754
|
+
import { mountJUnitViewer } from 'omni-viewer-core/viewers/junit';
|
|
755
|
+
|
|
756
|
+
const { viewerId } = detectViewer(file.name, undefined, undefined, undefined, text);
|
|
757
|
+
if (viewerId === 'junit') await mountJUnitViewer({ fileName: file.name, data: bytes }, container, { ...ctx, clipboard });
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
`parseJUnit` is a contract parser (`ParseOutcome<JUnitDocument>`) built on the
|
|
761
|
+
core XML scanner, so it has no DOM dependency, never loads external entities,
|
|
762
|
+
and recovers a truncated report as `partial`. It reads nested suites, test cases
|
|
763
|
+
with their `failure`/`error`/`skipped` results (and Surefire's flaky/rerun
|
|
764
|
+
attempts), properties, and suite or case `system-out`/`system-err`. Writers
|
|
765
|
+
disagree about the declared totals, so every count is recomputed from the
|
|
766
|
+
cases; declared totals that differ are reported, not trusted. A `failure` or
|
|
767
|
+
`error` placed directly in a suite becomes a synthetic case so a setup error
|
|
768
|
+
shows in the list.
|
|
769
|
+
|
|
770
|
+
The viewer opens on the first failing test with a pass/fail verdict, an
|
|
771
|
+
outcome bar and summary figures (tests, passed, failed, errors, skipped, pass
|
|
772
|
+
rate, duration). The test list is filterable by status, suite subtree, and free
|
|
773
|
+
text over names, classes, and messages, with an opt-in toggle that extends the
|
|
774
|
+
search to stack traces and captured output. It is sortable by status severity,
|
|
775
|
+
name, suite, and time. The detail pane shows each result's message, type, and
|
|
776
|
+
trace, the captured output, and properties, and **Copy failure details** puts a
|
|
777
|
+
plain-text report on the clipboard. A suites tab lists nested suites with
|
|
778
|
+
rolled-up counts, and the source tab shows the report text. Defaults are 64 MiB
|
|
779
|
+
input, 100,000 cases, 64 KiB per trace or output block, and 16 MiB of captured
|
|
780
|
+
output in total. See the [viewer contract](docs/viewers/junit.md) and
|
|
781
|
+
[examples](examples/junit/README.md).
|
|
782
|
+
|
|
538
783
|
### EPUB e-books (.epub)
|
|
539
784
|
|
|
540
785
|
EPUB 2.0.1 and EPUB 3.x books open in a reflowable reading pane with the
|
|
@@ -607,7 +852,8 @@ XPath (positions appear only where names repeat), the value, or the node's XML.
|
|
|
607
852
|
Both panes are virtualized, and long single-line sources are split into
|
|
608
853
|
display segments. Defaults are 64 MiB input, 500,000 nodes, and depth 1,000.
|
|
609
854
|
ARXML and ReqIF keep their dedicated viewers by extension. An `.xml` whose root
|
|
610
|
-
is an OpenVINO IR goes to the OpenVINO
|
|
855
|
+
is an OpenVINO IR or a JUnit test report goes to the OpenVINO or JUnit viewer
|
|
856
|
+
when a text sample is provided.
|
|
611
857
|
|
|
612
858
|
### Archive host integration
|
|
613
859
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
This distribution includes the following third-party software.
|
|
4
4
|
|
|
5
|
+
## Three.js (optional peer)
|
|
6
|
+
|
|
7
|
+
- Project: Three.js (`three`)
|
|
8
|
+
- Copyright: 2010-2025 three.js authors
|
|
9
|
+
- License: MIT
|
|
10
|
+
- Use: 3D mesh rendering, GLB/glTF/STL/OBJ loaders and orbit controls
|
|
11
|
+
- Source: https://github.com/mrdoob/three.js
|
|
12
|
+
|
|
13
|
+
Three.js is supplied by the consuming host; the core does not redistribute its
|
|
14
|
+
runtime. Retain the upstream MIT license when bundling it in an application.
|
|
15
|
+
|
|
5
16
|
## Hugging Face GGUF parser
|
|
6
17
|
|
|
7
18
|
- Project: `@huggingface/gguf` and `@huggingface/tasks`
|
|
@@ -55,3 +66,15 @@ rhwp project, used only for tests and never published to the npm package.
|
|
|
55
66
|
- License: MIT
|
|
56
67
|
- Source: https://github.com/edwardkim/rhwp (`rhwp-studio/public/samples/`,
|
|
57
68
|
`samples/valign_fixtures/`)
|
|
69
|
+
|
|
70
|
+
## JUnit example reports
|
|
71
|
+
|
|
72
|
+
`examples/junit/jenkins-nested-testsuites.xml` and
|
|
73
|
+
`examples/junit/jenkins-suite-error.xml` are unmodified test fixtures from the
|
|
74
|
+
Jenkins JUnit plugin, used for examples and tests and never published to the
|
|
75
|
+
npm package.
|
|
76
|
+
|
|
77
|
+
- Project: jenkinsci/junit-plugin (commit `04461ad56caf19b05bc16015f23675883df83d43`)
|
|
78
|
+
- Copyright: (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
|
|
79
|
+
- License: MIT
|
|
80
|
+
- Source: https://github.com/jenkinsci/junit-plugin/tree/04461ad56caf19b05bc16015f23675883df83d43/src/test/resources/hudson/tasks/junit
|
package/dist/i18n/catalog.en.js
CHANGED
|
@@ -4,6 +4,217 @@
|
|
|
4
4
|
// this catalog at build time. Diagnostics (§3-① messageKey) and viewer UI
|
|
5
5
|
// strings share this key space.
|
|
6
6
|
export const CATALOG_EN = {
|
|
7
|
+
// Plain text
|
|
8
|
+
'text.title': 'Plain text',
|
|
9
|
+
'text.encoding': 'Encoding: {encoding}',
|
|
10
|
+
'text.wrap': 'Wrap lines',
|
|
11
|
+
'text.truncated': 'Showing a preview of the first {bytes} bytes. The rest of the file is not displayed.',
|
|
12
|
+
'text.invalidEncoding': 'Some bytes are not valid {encoding} and are shown as replacement characters. Legacy encodings are not detected automatically.',
|
|
13
|
+
'text.unsupportedEncoding': 'UTF-32 text is not supported. Convert the file to UTF-8 or UTF-16 to view it.',
|
|
14
|
+
// DICOM
|
|
15
|
+
"dicom.title": "DICOM",
|
|
16
|
+
"dicom.summary": "{modality} · {width} × {height} · {bits}-bit · {frames} frames",
|
|
17
|
+
"dicom.controls": "Image controls",
|
|
18
|
+
"dicom.frame": "Frame",
|
|
19
|
+
"dicom.frameStatus": "Frame {frame} / {frames}",
|
|
20
|
+
"dicom.previous": "Previous",
|
|
21
|
+
"dicom.next": "Next",
|
|
22
|
+
"dicom.center": "Window center",
|
|
23
|
+
"dicom.width": "Window width",
|
|
24
|
+
"dicom.reset": "Reset",
|
|
25
|
+
"dicom.invert": "Invert",
|
|
26
|
+
"dicom.zoom": "Zoom (%)",
|
|
27
|
+
"dicom.image": "DICOM image preview",
|
|
28
|
+
"dicom.metadata": "DICOM metadata",
|
|
29
|
+
"dicom.search": "Search tags, names, or values",
|
|
30
|
+
"dicom.tag": "Tag",
|
|
31
|
+
"dicom.name": "Attribute",
|
|
32
|
+
"dicom.vr": "VR",
|
|
33
|
+
"dicom.value": "Value",
|
|
34
|
+
"dicom.unknown": "Unknown / private attribute",
|
|
35
|
+
"dicom.sequence": "Sequence",
|
|
36
|
+
"dicom.binary": "Binary data ({bytes} bytes)",
|
|
37
|
+
"dicom.empty": "No matching attributes.",
|
|
38
|
+
"dicom.page": "Page {page} / {pages} · {count} attributes",
|
|
39
|
+
"dicom.unsupportedSyntax": "Image preview is unavailable for transfer syntax {syntax}. Compressed images require an external decoder. Metadata is available below.",
|
|
40
|
+
"dicom.noPixels": "This DICOM object has no image Pixel Data. Metadata is available below.",
|
|
41
|
+
"dicom.unsupportedPixels": "Image preview supports native 8-bit and 16-bit integer pixels. Metadata is available below.",
|
|
42
|
+
"dicom.unsupportedColor": "Image preview is unavailable for color format {color}. Metadata is available below.",
|
|
43
|
+
"dicom.unsupportedTransform": "This image uses a modality lookup table or enhanced per-frame transformations that are not supported. Metadata is available below.",
|
|
44
|
+
"dicom.renderFailed": "Image preview could not be rendered. Metadata is available below.",
|
|
45
|
+
"dicom.charset": "Character set {charset} is not supported; some text may display incorrectly.",
|
|
46
|
+
"dicom.voiLut": "A VOI lookup table is present. This preview uses windowing instead of the lookup table.",
|
|
47
|
+
"dicom.voiFunction": "VOI function {function} is not supported; using linear windowing.",
|
|
48
|
+
// OpenAPI / Swagger
|
|
49
|
+
"openapi.textLimited": "Some text is shortened to keep this view responsive. The complete document is available in the source tab.",
|
|
50
|
+
"openapi.referencedDefinition": "Referenced definition",
|
|
51
|
+
"openapi.title": "OpenAPI / Swagger",
|
|
52
|
+
"openapi.operations": "API documentation",
|
|
53
|
+
"openapi.schemas": "Schemas",
|
|
54
|
+
"openapi.security": "Authentication",
|
|
55
|
+
"openapi.source": "Original JSON / YAML",
|
|
56
|
+
"openapi.summary": "{operations} operations · {schemas} schemas",
|
|
57
|
+
"openapi.search": "Search paths, descriptions, or operation IDs",
|
|
58
|
+
"openapi.method": "HTTP method",
|
|
59
|
+
"openapi.tag": "Tag",
|
|
60
|
+
"openapi.allMethods": "All methods",
|
|
61
|
+
"openapi.allTags": "All tags",
|
|
62
|
+
"openapi.details": "Operation details",
|
|
63
|
+
"openapi.definition": "View definition (JSON)",
|
|
64
|
+
"openapi.name": "Name",
|
|
65
|
+
"openapi.type": "Type",
|
|
66
|
+
"openapi.required": "Required",
|
|
67
|
+
"openapi.description": "Description",
|
|
68
|
+
"openapi.yes": "Yes",
|
|
69
|
+
"openapi.no": "No",
|
|
70
|
+
"openapi.none": "None",
|
|
71
|
+
"openapi.example": "Example",
|
|
72
|
+
"openapi.webhook": "Webhook",
|
|
73
|
+
"openapi.deprecated": "Deprecated",
|
|
74
|
+
"openapi.servers": "Servers",
|
|
75
|
+
"openapi.parameters": "Parameters",
|
|
76
|
+
"openapi.parameter": "Parameter",
|
|
77
|
+
"openapi.in": "Location",
|
|
78
|
+
"openapi.requestBody": "Request body",
|
|
79
|
+
"openapi.responses": "Responses",
|
|
80
|
+
"openapi.headers": "Headers",
|
|
81
|
+
"openapi.consumes": "Request media types",
|
|
82
|
+
"openapi.securityAlternatives": "One alternative is required. Schemes joined with + are required together.",
|
|
83
|
+
"openapi.noSecurity": "No authentication requirement is declared.",
|
|
84
|
+
"openapi.anonymous": "Anonymous access is allowed.",
|
|
85
|
+
"openapi.operationSource": "View operation definition",
|
|
86
|
+
"openapi.copySource": "Copy source",
|
|
87
|
+
"openapi.copyPath": "Copy path",
|
|
88
|
+
"openapi.copyOperation": "Copy operation JSON",
|
|
89
|
+
"openapi.noClipboard": "Clipboard is unavailable on this host.",
|
|
90
|
+
"openapi.copied": "Copied.",
|
|
91
|
+
"openapi.copyFailed": "Could not copy to the clipboard.",
|
|
92
|
+
"openapi.previous": "Previous",
|
|
93
|
+
"openapi.next": "Next",
|
|
94
|
+
"openapi.page": "{page} / {pages}",
|
|
95
|
+
"openapi.results": "{count} / {total} operations",
|
|
96
|
+
"openapi.empty": "No matching operations.",
|
|
97
|
+
"openapi.rowsLimited": "Showing the first {count} rows. The full definition is available below.",
|
|
98
|
+
"openapi.sourceLimited": "Source preview is limited to {count} characters.",
|
|
99
|
+
"diag.openapi.invalid": "This is not a supported, well-formed OpenAPI / Swagger document. Showing the source.",
|
|
100
|
+
"diag.openapi.inputLimit": "The OpenAPI document exceeds the input size limit. Showing a source preview.",
|
|
101
|
+
"diag.openapi.parseLimit": "Parsing stopped at the configured resource limit.",
|
|
102
|
+
"diag.openapi.operationLimit": "Showing {count} operations because a resource limit was reached.",
|
|
103
|
+
"diag.openapi.reference": "Reference could not be resolved locally: {ref}. External documents are not loaded.",
|
|
104
|
+
"eml.title": "EML email",
|
|
105
|
+
"eml.noSubject": "(No subject)",
|
|
106
|
+
"eml.from": "From",
|
|
107
|
+
"eml.to": "To",
|
|
108
|
+
"eml.cc": "Cc",
|
|
109
|
+
"eml.bcc": "Bcc",
|
|
110
|
+
"eml.replyTo": "Reply-To",
|
|
111
|
+
"eml.date": "Date",
|
|
112
|
+
"eml.messageId": "Message-ID",
|
|
113
|
+
"eml.html": "HTML",
|
|
114
|
+
"eml.text": "Text",
|
|
115
|
+
"eml.headers": "Headers",
|
|
116
|
+
"eml.source": "Source",
|
|
117
|
+
"eml.copyText": "Copy text",
|
|
118
|
+
"eml.copyFailed": "Could not copy the message text.",
|
|
119
|
+
"eml.attachments": "Attachments ({count})",
|
|
120
|
+
"eml.saveAttachment": "Save",
|
|
121
|
+
"eml.saveNamedAttachment": "Save {name}",
|
|
122
|
+
"eml.noSave": "Attachment saving is unavailable in this host.",
|
|
123
|
+
"eml.saveFailed": "Could not save the attachment.",
|
|
124
|
+
"eml.noBody": "This message has no displayable body.",
|
|
125
|
+
"eml.htmlUnavailable": "This HTML body is too large or complex to preview. Use the source view.",
|
|
126
|
+
"eml.sourceTruncated": "Showing the first {limit} bytes of the source.",
|
|
127
|
+
"diag.eml.invalid-format": "This file does not contain a recognizable email message.",
|
|
128
|
+
"diag.eml.corrupted": "This email message is corrupted.",
|
|
129
|
+
"diag.eml.limit-exceeded": "This email exceeds the parsing limits.",
|
|
130
|
+
"diag.eml.aborted": "Email parsing was cancelled.",
|
|
131
|
+
"diag.eml.headers": "Some malformed email headers were ignored.",
|
|
132
|
+
"diag.eml.charset": "An unsupported character encoding was replaced with UTF-8.",
|
|
133
|
+
"diag.eml.encoding": "Some message content could not be decoded.",
|
|
134
|
+
"diag.eml.multipart": "A MIME boundary is missing or incomplete. Some content may be unavailable.",
|
|
135
|
+
"diag.eml.preview": "A message body was truncated to the preview limit.",
|
|
136
|
+
"diag.mesh.objPrimitives": "OBJ line and point primitives are omitted. Triangle meshes are displayed.",
|
|
137
|
+
"mcap.title": "MCAP",
|
|
138
|
+
"mcap.profile": "Profile",
|
|
139
|
+
"mcap.library": "Writer library",
|
|
140
|
+
"mcap.fileSize": "File size",
|
|
141
|
+
"mcap.messages": "Messages",
|
|
142
|
+
"mcap.channels": "Topics / channels",
|
|
143
|
+
"mcap.schemas": "Schemas",
|
|
144
|
+
"mcap.startTime": "Start time",
|
|
145
|
+
"mcap.endTime": "End time",
|
|
146
|
+
"mcap.duration": "Duration",
|
|
147
|
+
"mcap.metadata": "Metadata",
|
|
148
|
+
"mcap.attachments": "Attachments",
|
|
149
|
+
"mcap.chunks": "Chunks",
|
|
150
|
+
"mcap.search": "Search this tab",
|
|
151
|
+
"mcap.topic": "Topic",
|
|
152
|
+
"mcap.allTopics": "All topics",
|
|
153
|
+
"mcap.copyJson": "Copy JSON",
|
|
154
|
+
"mcap.payload": "Payload / schema preview",
|
|
155
|
+
"mcap.text": "Text",
|
|
156
|
+
"mcap.hex": "Hex",
|
|
157
|
+
"mcap.close": "Close preview",
|
|
158
|
+
"mcap.id": "ID",
|
|
159
|
+
"mcap.encoding": "Encoding",
|
|
160
|
+
"mcap.schema": "Schema",
|
|
161
|
+
"mcap.sequence": "Sequence",
|
|
162
|
+
"mcap.logTime": "Log time",
|
|
163
|
+
"mcap.publishTime": "Publish time",
|
|
164
|
+
"mcap.size": "Bytes",
|
|
165
|
+
"mcap.name": "Name",
|
|
166
|
+
"mcap.key": "Key",
|
|
167
|
+
"mcap.value": "Value",
|
|
168
|
+
"mcap.mediaType": "Media type",
|
|
169
|
+
"mcap.createTime": "Creation time",
|
|
170
|
+
"mcap.offset": "Offset",
|
|
171
|
+
"mcap.compression": "Compression",
|
|
172
|
+
"mcap.compressed": "Compressed bytes",
|
|
173
|
+
"mcap.uncompressed": "Uncompressed bytes",
|
|
174
|
+
"mcap.decoded": "Decoded",
|
|
175
|
+
"mcap.none": "None",
|
|
176
|
+
"mcap.yes": "Yes",
|
|
177
|
+
"mcap.no": "No",
|
|
178
|
+
"mcap.inspect": "Inspect",
|
|
179
|
+
"mcap.empty": "No matching records in this tab.",
|
|
180
|
+
"mcap.truncated": "This is a truncated preview. The full payload is larger.",
|
|
181
|
+
"mcap.payloadHint": "Binary encodings (CDR, Protobuf, ROS) can be inspected as raw hex. Timestamps use the recording's epoch.",
|
|
182
|
+
"mcap.rows": "{count} retained records",
|
|
183
|
+
"mcap.copyFailed": "Could not copy JSON.",
|
|
184
|
+
"diag.mcap.invalid-format": "This is not an MCAP v0 file.",
|
|
185
|
+
"diag.mcap.corrupted": "MCAP data is truncated or malformed. Any recovered records are shown.",
|
|
186
|
+
"diag.mcap.limit-exceeded": "MCAP parsing stopped at a resource limit. Totals may be incomplete.",
|
|
187
|
+
"diag.mcap.aborted": "MCAP parsing was cancelled.",
|
|
188
|
+
"diag.mcap.preview": "Preview limits were reached. Only retained samples are searchable and copied; counts still include scanned messages.",
|
|
189
|
+
"diag.mcap.compression": "Some compressed chunks could not be read. Supply LZ4/Zstd decoders or use the self-loading entry with lz4js and fzstd installed. Summary records are still shown.",
|
|
190
|
+
"diag.mcap.unsupportedCompression": "Chunks with an unsupported compression codec were skipped. Totals may be incomplete.",
|
|
191
|
+
"diag.mcap.schemaZero": "An invalid schema with ID 0 was ignored.",
|
|
192
|
+
"diag.mcap.references": "Some channels or schemas referenced by messages are missing.",
|
|
193
|
+
"diag.mcap.crc": "An MCAP checksum does not match. Recovered data may be damaged.",
|
|
194
|
+
"mesh.title": "3D Mesh",
|
|
195
|
+
"mesh.summary": "{format} · {meshes} meshes · {vertices} vertices · {triangles} triangles",
|
|
196
|
+
"mesh.controls": "3D controls",
|
|
197
|
+
"mesh.fit": "Fit to view",
|
|
198
|
+
"mesh.zoomIn": "Zoom in",
|
|
199
|
+
"mesh.zoomOut": "Zoom out",
|
|
200
|
+
"mesh.wireframe": "Wireframe",
|
|
201
|
+
"mesh.grid": "Grid",
|
|
202
|
+
"mesh.axes": "Axes",
|
|
203
|
+
"mesh.play": "Play animation",
|
|
204
|
+
"mesh.pause": "Pause animation",
|
|
205
|
+
"mesh.viewport": "Interactive 3D model",
|
|
206
|
+
"mesh.hint": "Drag to rotate · Right-drag to pan · Scroll to zoom · Arrow keys to rotate · Home to reset",
|
|
207
|
+
"mesh.missingAsset": "The model asset could not be loaded: {path}",
|
|
208
|
+
"mesh.decodeFailed": "The 3D model could not be decoded. The data may be damaged or require a host-provided compression decoder.",
|
|
209
|
+
"mesh.empty": "No renderable mesh with valid bounds was found.",
|
|
210
|
+
"mesh.webglUnavailable": "3D rendering requires WebGL 2. Check your browser and graphics settings.",
|
|
211
|
+
"mesh.missingDependency": "Install the optional three package to display 3D models.",
|
|
212
|
+
"mesh.textureFailed": "Some model textures could not be loaded. Geometry is still displayed.",
|
|
213
|
+
"mesh.contextLost": "The graphics context was lost. Waiting for it to recover.",
|
|
214
|
+
"diag.mesh.invalid": "Unsupported 3D format. Expected GLB, glTF, STL, or OBJ.",
|
|
215
|
+
"diag.mesh.corrupted": "The 3D model is truncated, malformed, or contains invalid coordinates or resource paths.",
|
|
216
|
+
"diag.mesh.limit": "The 3D model exceeds the configured resource limit.",
|
|
217
|
+
"diag.mesh.objMaterials": "OBJ material libraries are not loaded. Geometry uses default materials.",
|
|
7
218
|
"font.fallback": "Characters missing from this font are displayed using a fallback font.",
|
|
8
219
|
"font.title": "Font",
|
|
9
220
|
"font.format": "Format",
|
|
@@ -572,6 +783,93 @@ export const CATALOG_EN = {
|
|
|
572
783
|
'diag.epub.toc-missing': 'The book has no table of contents; chapters are listed in reading order.',
|
|
573
784
|
'diag.epub.time-limit': 'Parsing stopped at the time limit; the book may be incomplete.',
|
|
574
785
|
'diag.epub.fixed-layout': 'This is a fixed-layout book; pages are shown as reflowable text.',
|
|
786
|
+
// JUnit XML test report
|
|
787
|
+
"junit.title": "JUnit test report",
|
|
788
|
+
"junit.unreadable": "This file could not be read as a JUnit test report.",
|
|
789
|
+
"junit.report": "Test report",
|
|
790
|
+
"junit.unnamed": "(unnamed)",
|
|
791
|
+
"junit.suiteCount": "{count} suites",
|
|
792
|
+
"junit.caseCount": "{count} tests",
|
|
793
|
+
"junit.verdict.passed": "All tests passed",
|
|
794
|
+
"junit.verdict.failed": "{count} failing",
|
|
795
|
+
"junit.verdict.empty": "No tests",
|
|
796
|
+
"junit.verdict.incomplete": "No failures in the {count} tests read — report incomplete",
|
|
797
|
+
"junit.verdict.skipped": "All {count} skipped",
|
|
798
|
+
"junit.summary.tests": "Tests",
|
|
799
|
+
"junit.summary.passed": "Passed",
|
|
800
|
+
"junit.summary.failed": "Failed",
|
|
801
|
+
"junit.summary.errors": "Errors",
|
|
802
|
+
"junit.summary.skipped": "Skipped",
|
|
803
|
+
"junit.summary.flaky": "Flaky",
|
|
804
|
+
"junit.summary.passRate": "Pass rate",
|
|
805
|
+
"junit.summary.duration": "Duration",
|
|
806
|
+
"junit.summary.suites": "Suites",
|
|
807
|
+
"junit.search": "Search tests, classes, messages…",
|
|
808
|
+
"junit.searchOutput": "Search output and stack traces",
|
|
809
|
+
"junit.filter.status": "Status",
|
|
810
|
+
"junit.filter.allStatuses": "All statuses",
|
|
811
|
+
"junit.filter.problems": "Failures and errors",
|
|
812
|
+
"junit.filter.suite": "Suite",
|
|
813
|
+
"junit.filter.allSuites": "All suites",
|
|
814
|
+
"junit.tab.tests": "Tests",
|
|
815
|
+
"junit.tab.suites": "Suites",
|
|
816
|
+
"junit.tab.source": "Source",
|
|
817
|
+
"junit.copyCase": "Copy failure details",
|
|
818
|
+
"junit.copySource": "Copy source",
|
|
819
|
+
"junit.copied": "Copied to clipboard.",
|
|
820
|
+
"junit.copyFailed": "Could not copy to the clipboard.",
|
|
821
|
+
"junit.status.passed": "Passed",
|
|
822
|
+
"junit.status.failed": "Failed",
|
|
823
|
+
"junit.status.error": "Error",
|
|
824
|
+
"junit.status.skipped": "Skipped",
|
|
825
|
+
"junit.status.flaky": "Flaky",
|
|
826
|
+
"junit.result.failure": "Failure",
|
|
827
|
+
"junit.result.error": "Error",
|
|
828
|
+
"junit.result.skipped": "Skipped",
|
|
829
|
+
"junit.result.flakyFailure": "Flaky failure",
|
|
830
|
+
"junit.result.flakyError": "Flaky error",
|
|
831
|
+
"junit.result.rerunFailure": "Rerun failure",
|
|
832
|
+
"junit.result.rerunError": "Rerun error",
|
|
833
|
+
"junit.rows": "{shown} / {total} rows shown",
|
|
834
|
+
"junit.moreRows": "{count} more…",
|
|
835
|
+
"junit.noMatches": "No tests match the current filters.",
|
|
836
|
+
"junit.noCases": "This report contains no test cases.",
|
|
837
|
+
"junit.noSuites": "This report contains no test suites.",
|
|
838
|
+
"junit.selectCase": "Select a test to inspect it.",
|
|
839
|
+
"junit.selectedHidden": "the selected test is past these rows; filter or search to show it",
|
|
840
|
+
"junit.column.index": "#",
|
|
841
|
+
"junit.column.status": "Status",
|
|
842
|
+
"junit.column.name": "Test",
|
|
843
|
+
"junit.column.suite": "Suite",
|
|
844
|
+
"junit.column.time": "Time",
|
|
845
|
+
"junit.column.tests": "Tests",
|
|
846
|
+
"junit.detail.general": "General",
|
|
847
|
+
"junit.detail.properties": "Properties",
|
|
848
|
+
"junit.detail.systemOut": "Standard output",
|
|
849
|
+
"junit.detail.systemErr": "Standard error",
|
|
850
|
+
"junit.field.status": "Status",
|
|
851
|
+
"junit.field.classname": "Class",
|
|
852
|
+
"junit.field.suite": "Suite",
|
|
853
|
+
"junit.field.time": "Time",
|
|
854
|
+
"junit.field.file": "Source file",
|
|
855
|
+
"junit.field.timestamp": "Timestamp",
|
|
856
|
+
"junit.field.hostname": "Host",
|
|
857
|
+
"junit.field.package": "Package",
|
|
858
|
+
"junit.field.id": "ID",
|
|
859
|
+
"junit.syntheticCase": "This failure is recorded on the suite itself rather than on a test case — typically a setup or teardown error.",
|
|
860
|
+
"junit.textTruncated": "Text shortened to keep this view responsive; copy the source for the complete text.",
|
|
861
|
+
"junit.sourceTruncated": "Source preview limited to the first {chars} characters.",
|
|
862
|
+
"junit.showTests": "Show tests",
|
|
863
|
+
"junit.countMismatch": "Declared totals differ from the test cases in this file",
|
|
864
|
+
"junit.countMismatchDetail": "The totals this suite declares differ from the test cases it contains. The counts shown are recomputed from the test cases.",
|
|
865
|
+
"junit.declaredDiffers": "{found} (declared {declared})",
|
|
866
|
+
"diag.junit.notJunit": "The root element <{root}> is not a JUnit <testsuites> or <testsuite>.",
|
|
867
|
+
"diag.junit.caseLimit": "Showing the first {shown} of {total} test cases.",
|
|
868
|
+
"diag.junit.caseLimitAtLeast": "Showing the first {shown} of at least {total} test cases; the report was cut off before the rest.",
|
|
869
|
+
"diag.junit.depthLimit": "Suites nested deeper than {depth} levels are not shown.",
|
|
870
|
+
"diag.junit.suiteLimit": "Only the first {max} test suites are shown; the rest of the report is not.",
|
|
871
|
+
"diag.junit.outputBudget": "Captured output beyond {chars} characters in total is not shown.",
|
|
872
|
+
"diag.junit.countMismatch": "Declared totals differ from the test cases in {count} suites; counts are recomputed from the test cases.",
|
|
575
873
|
'har.title': 'HAR network log',
|
|
576
874
|
'har.search': 'Search URL, status, headers…', 'har.searchBodies': 'Search bodies',
|
|
577
875
|
'har.version': 'HAR {version}', 'har.requestCount': '{count} requests', 'har.unknownCreator': 'Unknown writer',
|