-
+
+
+
diff --git a/src/test/fixtures/example-symbol-table.ts b/src/test/fixtures/example-symbol-table.ts
index 509aa8d79b..40af714732 100644
--- a/src/test/fixtures/example-symbol-table.ts
+++ b/src/test/fixtures/example-symbol-table.ts
@@ -280,3 +280,45 @@ export const partialSymbolTable: ExampleSymbolTable = {
export const completeSymbolTableAsTuple = completeSymbolTable.asTuple;
export const partialSymbolTableAsTuple = partialSymbolTable.asTuple;
+
+// A symbol table for a JIT dump file (e.g. jit-52344.dump), simulating JS
+// functions symbolicated from samply + jitdump. The outer function
+// "renderButton.js" has an inlined call to "useState.js" at address 0x000a.
+const jitDumpSyms = [
+ {
+ address: 0,
+ name: 'renderButton.js',
+ file: 'Button.tsx',
+ lineRanges: [
+ {
+ startAddress: 0x0,
+ line: 42,
+ },
+ {
+ startAddress: 0x8,
+ line: 45,
+ inlinedCall: {
+ name: 'useState.js',
+ file: 'react.js',
+ lineRanges: [
+ {
+ startAddress: 0x8,
+ line: 100,
+ },
+ ],
+ },
+ },
+ ],
+ },
+ {
+ address: 0x2000,
+ name: 'runJobs.js',
+ file: 'scheduler.js',
+ },
+];
+
+export const jitDumpSymbolTable: ExampleSymbolTable = {
+ symbols: jitDumpSyms,
+ asTuple: _makeSymbolTableAsTuple(jitDumpSyms),
+ getAddressResult: _makeGetAddressResultFunction(jitDumpSyms),
+};
diff --git a/src/test/fixtures/profiles/processed-profile.ts b/src/test/fixtures/profiles/processed-profile.ts
index 5961d2c0bf..428b559836 100644
--- a/src/test/fixtures/profiles/processed-profile.ts
+++ b/src/test/fixtures/profiles/processed-profile.ts
@@ -33,6 +33,7 @@ import type {
CategoryList,
JsTracerTable,
RawCounter,
+ CounterDisplayConfig,
TabID,
MarkerPayload,
NetworkPayload,
@@ -1479,6 +1480,18 @@ export function getProfileWithJsTracerEvents(
return profile;
}
+/**
+ * Default display configuration for test counters.
+ */
+const DEFAULT_TEST_COUNTER_DISPLAY: CounterDisplayConfig = {
+ graphType: 'line-rate',
+ unit: '',
+ color: 'grey',
+ markerSchemaLocation: null,
+ sortWeight: 50,
+ label: 'My Counter',
+};
+
/**
* Creates a Counter fixture for a given thread.
*/
@@ -1504,6 +1517,7 @@ export function getCounterForThread(
count: sampleTimes.map((_, i) => Math.sin(i)),
length: thread.samples.length,
},
+ display: DEFAULT_TEST_COUNTER_DISPLAY,
};
return counter;
}
@@ -1541,6 +1555,7 @@ export function getCounterForThreadWithSamples(
pid: thread.pid,
mainThreadIndex,
samples: newSamples,
+ display: DEFAULT_TEST_COUNTER_DISPLAY,
};
return counter;
}
diff --git a/src/test/fixtures/profiles/tracks.ts b/src/test/fixtures/profiles/tracks.ts
index ae23c71340..88df189e41 100644
--- a/src/test/fixtures/profiles/tracks.ts
+++ b/src/test/fixtures/profiles/tracks.ts
@@ -88,22 +88,11 @@ export function getHumanReadableTracks(state: State): string[] {
for (const trackIndex of trackOrder) {
const track = tracks[trackIndex];
let trackName;
- if (track.type === 'memory') {
- trackName = profileViewSelectors
+ if (track.type === 'counter') {
+ const counter = profileViewSelectors
.getCounterSelectors(track.counterIndex)
- .getPid(state);
- } else if (track.type === 'bandwidth') {
- trackName = profileViewSelectors
- .getCounterSelectors(track.counterIndex)
- .getPid(state);
- } else if (track.type === 'process-cpu') {
- trackName = profileViewSelectors
- .getCounterSelectors(track.counterIndex)
- .getPid(state);
- } else if (track.type === 'power') {
- trackName = profileViewSelectors
- .getCounterSelectors(track.counterIndex)
- .getCounter(state).name;
+ .getCounter(state);
+ trackName = counter.display.label || counter.name;
} else if (track.type === 'marker') {
trackName = stringArray[track.markerName];
} else {
@@ -297,6 +286,15 @@ export function getStoreWithMemoryTrack(pid: Pid = '222') {
thread.pid = pid;
const counter = getCounterForThread(thread, threadIndex);
counter.category = 'Memory';
+ counter.display = {
+ ...counter.display,
+ graphType: 'line-accumulated',
+ unit: 'bytes',
+ color: 'orange',
+ markerSchemaLocation: 'timeline-memory',
+ sortWeight: 20,
+ label: 'Memory',
+ };
profile.counters = [counter];
}
@@ -306,8 +304,8 @@ export function getStoreWithMemoryTrack(pid: Pid = '222') {
trackReference
);
- if (localTrack.type !== 'memory') {
- throw new Error('Expected a memory track.');
+ if (localTrack.type !== 'counter') {
+ throw new Error('Expected a counter track.');
}
return { store, ...store, profile, trackReference, localTrack, threadIndex };
}
diff --git a/src/test/fixtures/utils.ts b/src/test/fixtures/utils.ts
index 0f50030d9d..84290f4f7b 100644
--- a/src/test/fixtures/utils.ts
+++ b/src/test/fixtures/utils.ts
@@ -641,6 +641,26 @@ function isControlInput(element: HTMLElement): boolean {
);
}
+/**
+ * Returns an ArrayBuffer which contains only the bytes that are covered by the
+ * Uint8Array, making a copy if needed.
+ */
+export function extractArrayBuffer(
+ bufferView: Uint8Array
+): ArrayBuffer {
+ if (
+ bufferView.byteOffset === 0 &&
+ bufferView.byteLength === bufferView.buffer.byteLength
+ ) {
+ return bufferView.buffer;
+ }
+
+ // There was extra data at the start or at the end. Make a copy.
+ const copy = new Uint8Array(bufferView.byteLength);
+ copy.set(bufferView);
+ return copy.buffer;
+}
+
/**
* Adds a source entry to the sources table and returns the index.
* If a source with the same URL already exists, returns the existing index.
diff --git a/src/test/integration/profiler-edit/__snapshots__/profiler-edit.test.ts.snap b/src/test/integration/profiler-edit/__snapshots__/profiler-edit.test.ts.snap
new file mode 100644
index 0000000000..28da043c8d
--- /dev/null
+++ b/src/test/integration/profiler-edit/__snapshots__/profiler-edit.test.ts.snap
@@ -0,0 +1,5313 @@
+// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
+
+exports[`profiler-edit tool is symbolicating a .json.gz trace correctly 1`] = `
+Object {
+ "counters": Array [],
+ "libs": Array [
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "F635824E318B3F0C842CC369737F2B680",
+ "codeId": "F635824E318B3F0C842CC369737F2B68",
+ "debugName": "dyld",
+ "debugPath": "/usr/lib/dyld",
+ "name": "dyld",
+ "path": "/usr/lib/dyld",
+ },
+ Object {
+ "arch": "arm64",
+ "breakpadId": "F61DA4D57CBB38CA8BDF059C645834520",
+ "codeId": "F61DA4D57CBB38CA8BDF059C64583452",
+ "debugName": "a.out",
+ "debugPath": "/usr/helloworld/a.out",
+ "name": "a.out",
+ "path": "/usr/helloworld/a.out",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "E03E84786F5C3D21A79A58408F5140000",
+ "codeId": "E03E84786F5C3D21A79A58408F514000",
+ "debugName": "libsystem_pthread.dylib",
+ "debugPath": "/usr/lib/system/libsystem_pthread.dylib",
+ "name": "libsystem_pthread.dylib",
+ "path": "/usr/lib/system/libsystem_pthread.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "71FF45B8F14E36669E966CF58315B91D0",
+ "codeId": "71FF45B8F14E36669E966CF58315B91D",
+ "debugName": "libsystem_kernel.dylib",
+ "debugPath": "/usr/lib/system/libsystem_kernel.dylib",
+ "name": "libsystem_kernel.dylib",
+ "path": "/usr/lib/system/libsystem_kernel.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "D30F183093D03D0B8CBA9544E84BFD5B0",
+ "codeId": "D30F183093D03D0B8CBA9544E84BFD5B",
+ "debugName": "libsystem_c.dylib",
+ "debugPath": "/usr/lib/system/libsystem_c.dylib",
+ "name": "libsystem_c.dylib",
+ "path": "/usr/lib/system/libsystem_c.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "B4BF9F8931D737428CE7AB3554F9F5250",
+ "codeId": "B4BF9F8931D737428CE7AB3554F9F525",
+ "debugName": "libsystem_platform.dylib",
+ "debugPath": "/usr/lib/system/libsystem_platform.dylib",
+ "name": "libsystem_platform.dylib",
+ "path": "/usr/lib/system/libsystem_platform.dylib",
+ },
+ ],
+ "meta": Object {
+ "categories": Array [
+ Object {
+ "color": "grey",
+ "name": "Other",
+ "subcategories": Array [
+ "Other",
+ ],
+ },
+ Object {
+ "color": "yellow",
+ "name": "User",
+ "subcategories": Array [
+ "Other",
+ ],
+ },
+ ],
+ "debug": false,
+ "extensions": Object {
+ "baseURL": Array [],
+ "id": Array [],
+ "length": 0,
+ "name": Array [],
+ },
+ "interval": 1,
+ "markerSchema": Array [],
+ "oscpu": "macOS 14.6.1",
+ "pausedRanges": Array [],
+ "preprocessedProfileVersion": 62,
+ "processType": 0,
+ "product": "a.out",
+ "sampleUnits": Object {
+ "eventDelay": "ms",
+ "threadCPUDelta": "µs",
+ "time": "ms",
+ },
+ "sourceCodeIsNotOnSearchfox": true,
+ "startTime": 1726433495880.2869,
+ "symbolicated": true,
+ "usesOnlyOneStackType": true,
+ "version": 24,
+ },
+ "pages": Array [],
+ "profilerOverhead": Array [],
+ "shared": Object {
+ "frameTable": Object {
+ "address": Array [
+ 24915,
+ 16067,
+ 38027,
+ 11180,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28575,
+ 30367,
+ 18819,
+ 16188,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ ],
+ "category": Array [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ ],
+ "column": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "func": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 11,
+ 12,
+ 14,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ ],
+ "inlineDepth": Array [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ],
+ "innerWindowID": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "length": 42,
+ "line": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "nativeSymbol": Array [
+ 0,
+ 1,
+ 4,
+ 8,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 6,
+ 7,
+ 12,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ ],
+ "subcategory": Array [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ],
+ },
+ "funcTable": Object {
+ "columnNumber": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "isJS": Array [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ ],
+ "length": 15,
+ "lineNumber": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "name": Array [
+ 21,
+ 22,
+ 25,
+ 29,
+ 26,
+ 23,
+ 24,
+ 31,
+ 32,
+ 30,
+ 15,
+ 27,
+ 28,
+ 18,
+ 33,
+ ],
+ "relevantForJS": Array [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ ],
+ "resource": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 2,
+ 1,
+ 1,
+ 4,
+ 4,
+ 3,
+ 1,
+ 2,
+ 2,
+ 2,
+ 5,
+ ],
+ "source": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ },
+ "nativeSymbols": Object {
+ "address": Array [
+ 22440,
+ 15828,
+ 15752,
+ 15644,
+ 37420,
+ 28428,
+ 30256,
+ 18740,
+ 11172,
+ 17376,
+ 54332,
+ 54412,
+ 16080,
+ ],
+ "functionSize": Array [
+ 2788,
+ 380,
+ 76,
+ 108,
+ 1028,
+ 320,
+ 120,
+ 92,
+ 44,
+ 44,
+ 80,
+ 464,
+ 212,
+ ],
+ "length": 13,
+ "libIndex": Array [
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 2,
+ 2,
+ 2,
+ 3,
+ 3,
+ 4,
+ 4,
+ 5,
+ ],
+ "name": Array [
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31,
+ 32,
+ 33,
+ ],
+ },
+ "resourceTable": Object {
+ "host": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "length": 6,
+ "lib": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ ],
+ "name": Array [
+ 4,
+ 5,
+ 6,
+ 7,
+ 14,
+ 20,
+ ],
+ "type": Array [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ ],
+ },
+ "sources": Object {
+ "filename": Array [],
+ "id": Array [],
+ "length": 0,
+ "sourceMapURL": Array [],
+ "startColumn": Array [],
+ "startLine": Array [],
+ },
+ "stackTable": Object {
+ "frame": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 12,
+ 13,
+ 14,
+ 15,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 19,
+ 20,
+ 21,
+ 22,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 31,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ ],
+ "length": 88,
+ "prefix": Array [
+ null,
+ 0,
+ 1,
+ 2,
+ null,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ null,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 11,
+ 16,
+ 17,
+ 18,
+ 19,
+ null,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 22,
+ 27,
+ 28,
+ 29,
+ 30,
+ 27,
+ 32,
+ 33,
+ 34,
+ 35,
+ null,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 38,
+ 43,
+ 44,
+ 45,
+ 46,
+ 43,
+ 48,
+ 49,
+ 50,
+ 51,
+ 48,
+ 53,
+ 54,
+ 55,
+ 56,
+ null,
+ 58,
+ 59,
+ 60,
+ null,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 63,
+ 68,
+ 69,
+ 70,
+ 71,
+ 68,
+ 73,
+ 74,
+ 75,
+ 76,
+ 73,
+ 78,
+ 79,
+ 80,
+ 81,
+ 78,
+ 83,
+ 84,
+ 85,
+ 86,
+ ],
+ },
+ "stringArray": Array [
+ "0x6153",
+ "0x3ec3",
+ "0x948b",
+ "0x2bac",
+ "dyld",
+ "a.out",
+ "libsystem_pthread.dylib",
+ "libsystem_kernel.dylib",
+ "0x6f93",
+ "0x3db3",
+ "0x3d33",
+ "0xd47f",
+ "0xd567",
+ "0x43e8",
+ "libsystem_c.dylib",
+ "0x3d67",
+ "0x6f9f",
+ "0x769f",
+ "0x4983",
+ "0x3f3c",
+ "libsystem_platform.dylib",
+ "start",
+ "main",
+ "threadfunc(void*)",
+ "fac(unsigned long)",
+ "_pthread_join",
+ "_pthread_start",
+ "_pthread_exit",
+ "_pthread_terminate_invoke",
+ "__ulock_wait",
+ "__semwait_signal",
+ "usleep",
+ "nanosleep",
+ "_platform_memset",
+ ],
+ },
+ "threads": Array [
+ Object {
+ "isMainThread": true,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "a.out",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 237.805292,
+ "samples": Object {
+ "length": 11,
+ "stack": Array [
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ ],
+ "threadCPUDelta": Array [
+ 11273,
+ 0,
+ 8,
+ 0,
+ 3,
+ 4,
+ 0,
+ 30,
+ 0,
+ 21,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ 262.732625,
+ 263.723459,
+ 274.768584,
+ 275.7785,
+ 286.765084,
+ 287.756375,
+ 299.7795,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ 1,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 12,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274156",
+ "unregisterTime": 300.814417,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274161>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 2,
+ "stack": Array [
+ 9,
+ 9,
+ ],
+ "threadCPUDelta": Array [
+ 7,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274161",
+ "unregisterTime": 252.728334,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274162>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 4,
+ "stack": Array [
+ 15,
+ 15,
+ 20,
+ 20,
+ ],
+ "threadCPUDelta": Array [
+ 3,
+ 0,
+ 5,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274162",
+ "unregisterTime": 262.732625,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274163>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 6,
+ "stack": Array [
+ 26,
+ 26,
+ 31,
+ 31,
+ 36,
+ 36,
+ ],
+ "threadCPUDelta": Array [
+ 1,
+ 0,
+ 5,
+ 0,
+ 3,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 263.723459,
+ 264.733042,
+ 274.768584,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 10,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274163",
+ "unregisterTime": 275.7785,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274164>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 9,
+ "stack": Array [
+ 42,
+ 42,
+ 47,
+ 47,
+ 52,
+ 52,
+ 57,
+ 57,
+ 61,
+ ],
+ "threadCPUDelta": Array [
+ 6,
+ 0,
+ 9,
+ 0,
+ 20,
+ 0,
+ 6,
+ 0,
+ 2,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ 262.732625,
+ 273.755,
+ 274.768584,
+ 285.764042,
+ 286.765084,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274164",
+ "unregisterTime": 287.756375,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274165>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 10,
+ "stack": Array [
+ 67,
+ 67,
+ 72,
+ 72,
+ 77,
+ 77,
+ 82,
+ 82,
+ 87,
+ 87,
+ ],
+ "threadCPUDelta": Array [
+ 2,
+ 0,
+ 6,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 4,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 263.723459,
+ 264.733042,
+ 274.768584,
+ 275.7785,
+ 287.756375,
+ 288.76475,
+ 299.7795,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 10,
+ 1,
+ 12,
+ 1,
+ 11,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274165",
+ "unregisterTime": 300.814417,
+ },
+ ],
+}
+`;
+
+exports[`profiler-edit tool is symbolicating a trace correctly 1`] = `
+Object {
+ "counters": Array [],
+ "libs": Array [
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "F635824E318B3F0C842CC369737F2B680",
+ "codeId": "F635824E318B3F0C842CC369737F2B68",
+ "debugName": "dyld",
+ "debugPath": "/usr/lib/dyld",
+ "name": "dyld",
+ "path": "/usr/lib/dyld",
+ },
+ Object {
+ "arch": "arm64",
+ "breakpadId": "F61DA4D57CBB38CA8BDF059C645834520",
+ "codeId": "F61DA4D57CBB38CA8BDF059C64583452",
+ "debugName": "a.out",
+ "debugPath": "/usr/helloworld/a.out",
+ "name": "a.out",
+ "path": "/usr/helloworld/a.out",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "E03E84786F5C3D21A79A58408F5140000",
+ "codeId": "E03E84786F5C3D21A79A58408F514000",
+ "debugName": "libsystem_pthread.dylib",
+ "debugPath": "/usr/lib/system/libsystem_pthread.dylib",
+ "name": "libsystem_pthread.dylib",
+ "path": "/usr/lib/system/libsystem_pthread.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "71FF45B8F14E36669E966CF58315B91D0",
+ "codeId": "71FF45B8F14E36669E966CF58315B91D",
+ "debugName": "libsystem_kernel.dylib",
+ "debugPath": "/usr/lib/system/libsystem_kernel.dylib",
+ "name": "libsystem_kernel.dylib",
+ "path": "/usr/lib/system/libsystem_kernel.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "D30F183093D03D0B8CBA9544E84BFD5B0",
+ "codeId": "D30F183093D03D0B8CBA9544E84BFD5B",
+ "debugName": "libsystem_c.dylib",
+ "debugPath": "/usr/lib/system/libsystem_c.dylib",
+ "name": "libsystem_c.dylib",
+ "path": "/usr/lib/system/libsystem_c.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "B4BF9F8931D737428CE7AB3554F9F5250",
+ "codeId": "B4BF9F8931D737428CE7AB3554F9F525",
+ "debugName": "libsystem_platform.dylib",
+ "debugPath": "/usr/lib/system/libsystem_platform.dylib",
+ "name": "libsystem_platform.dylib",
+ "path": "/usr/lib/system/libsystem_platform.dylib",
+ },
+ ],
+ "meta": Object {
+ "categories": Array [
+ Object {
+ "color": "grey",
+ "name": "Other",
+ "subcategories": Array [
+ "Other",
+ ],
+ },
+ Object {
+ "color": "yellow",
+ "name": "User",
+ "subcategories": Array [
+ "Other",
+ ],
+ },
+ ],
+ "debug": false,
+ "extensions": Object {
+ "baseURL": Array [],
+ "id": Array [],
+ "length": 0,
+ "name": Array [],
+ },
+ "interval": 1,
+ "markerSchema": Array [],
+ "oscpu": "macOS 14.6.1",
+ "pausedRanges": Array [],
+ "preprocessedProfileVersion": 62,
+ "processType": 0,
+ "product": "a.out",
+ "sampleUnits": Object {
+ "eventDelay": "ms",
+ "threadCPUDelta": "µs",
+ "time": "ms",
+ },
+ "sourceCodeIsNotOnSearchfox": true,
+ "startTime": 1726433495880.2869,
+ "symbolicated": true,
+ "usesOnlyOneStackType": true,
+ "version": 24,
+ },
+ "pages": Array [],
+ "profilerOverhead": Array [],
+ "shared": Object {
+ "frameTable": Object {
+ "address": Array [
+ 24915,
+ 16067,
+ 38027,
+ 11180,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28575,
+ 30367,
+ 18819,
+ 16188,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ ],
+ "category": Array [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ ],
+ "column": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "func": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 11,
+ 12,
+ 14,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ ],
+ "inlineDepth": Array [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ],
+ "innerWindowID": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "length": 42,
+ "line": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "nativeSymbol": Array [
+ 0,
+ 1,
+ 4,
+ 8,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 6,
+ 7,
+ 12,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ ],
+ "subcategory": Array [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ],
+ },
+ "funcTable": Object {
+ "columnNumber": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "isJS": Array [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ ],
+ "length": 15,
+ "lineNumber": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "name": Array [
+ 21,
+ 22,
+ 25,
+ 29,
+ 26,
+ 23,
+ 24,
+ 31,
+ 32,
+ 30,
+ 15,
+ 27,
+ 28,
+ 18,
+ 33,
+ ],
+ "relevantForJS": Array [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ ],
+ "resource": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 2,
+ 1,
+ 1,
+ 4,
+ 4,
+ 3,
+ 1,
+ 2,
+ 2,
+ 2,
+ 5,
+ ],
+ "source": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ },
+ "nativeSymbols": Object {
+ "address": Array [
+ 22440,
+ 15828,
+ 15752,
+ 15644,
+ 37420,
+ 28428,
+ 30256,
+ 18740,
+ 11172,
+ 17376,
+ 54332,
+ 54412,
+ 16080,
+ ],
+ "functionSize": Array [
+ 2788,
+ 380,
+ 76,
+ 108,
+ 1028,
+ 320,
+ 120,
+ 92,
+ 44,
+ 44,
+ 80,
+ 464,
+ 212,
+ ],
+ "length": 13,
+ "libIndex": Array [
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 2,
+ 2,
+ 2,
+ 3,
+ 3,
+ 4,
+ 4,
+ 5,
+ ],
+ "name": Array [
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31,
+ 32,
+ 33,
+ ],
+ },
+ "resourceTable": Object {
+ "host": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "length": 6,
+ "lib": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ ],
+ "name": Array [
+ 4,
+ 5,
+ 6,
+ 7,
+ 14,
+ 20,
+ ],
+ "type": Array [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ ],
+ },
+ "sources": Object {
+ "filename": Array [],
+ "id": Array [],
+ "length": 0,
+ "sourceMapURL": Array [],
+ "startColumn": Array [],
+ "startLine": Array [],
+ },
+ "stackTable": Object {
+ "frame": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 12,
+ 13,
+ 14,
+ 15,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 19,
+ 20,
+ 21,
+ 22,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 31,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ ],
+ "length": 88,
+ "prefix": Array [
+ null,
+ 0,
+ 1,
+ 2,
+ null,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ null,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 11,
+ 16,
+ 17,
+ 18,
+ 19,
+ null,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 22,
+ 27,
+ 28,
+ 29,
+ 30,
+ 27,
+ 32,
+ 33,
+ 34,
+ 35,
+ null,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 38,
+ 43,
+ 44,
+ 45,
+ 46,
+ 43,
+ 48,
+ 49,
+ 50,
+ 51,
+ 48,
+ 53,
+ 54,
+ 55,
+ 56,
+ null,
+ 58,
+ 59,
+ 60,
+ null,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 63,
+ 68,
+ 69,
+ 70,
+ 71,
+ 68,
+ 73,
+ 74,
+ 75,
+ 76,
+ 73,
+ 78,
+ 79,
+ 80,
+ 81,
+ 78,
+ 83,
+ 84,
+ 85,
+ 86,
+ ],
+ },
+ "stringArray": Array [
+ "0x6153",
+ "0x3ec3",
+ "0x948b",
+ "0x2bac",
+ "dyld",
+ "a.out",
+ "libsystem_pthread.dylib",
+ "libsystem_kernel.dylib",
+ "0x6f93",
+ "0x3db3",
+ "0x3d33",
+ "0xd47f",
+ "0xd567",
+ "0x43e8",
+ "libsystem_c.dylib",
+ "0x3d67",
+ "0x6f9f",
+ "0x769f",
+ "0x4983",
+ "0x3f3c",
+ "libsystem_platform.dylib",
+ "start",
+ "main",
+ "threadfunc(void*)",
+ "fac(unsigned long)",
+ "_pthread_join",
+ "_pthread_start",
+ "_pthread_exit",
+ "_pthread_terminate_invoke",
+ "__ulock_wait",
+ "__semwait_signal",
+ "usleep",
+ "nanosleep",
+ "_platform_memset",
+ ],
+ },
+ "threads": Array [
+ Object {
+ "isMainThread": true,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "a.out",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 237.805292,
+ "samples": Object {
+ "length": 11,
+ "stack": Array [
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ ],
+ "threadCPUDelta": Array [
+ 11273,
+ 0,
+ 8,
+ 0,
+ 3,
+ 4,
+ 0,
+ 30,
+ 0,
+ 21,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ 262.732625,
+ 263.723459,
+ 274.768584,
+ 275.7785,
+ 286.765084,
+ 287.756375,
+ 299.7795,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ 1,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 12,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274156",
+ "unregisterTime": 300.814417,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274161>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 2,
+ "stack": Array [
+ 9,
+ 9,
+ ],
+ "threadCPUDelta": Array [
+ 7,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274161",
+ "unregisterTime": 252.728334,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274162>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 4,
+ "stack": Array [
+ 15,
+ 15,
+ 20,
+ 20,
+ ],
+ "threadCPUDelta": Array [
+ 3,
+ 0,
+ 5,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274162",
+ "unregisterTime": 262.732625,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274163>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 6,
+ "stack": Array [
+ 26,
+ 26,
+ 31,
+ 31,
+ 36,
+ 36,
+ ],
+ "threadCPUDelta": Array [
+ 1,
+ 0,
+ 5,
+ 0,
+ 3,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 263.723459,
+ 264.733042,
+ 274.768584,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 10,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274163",
+ "unregisterTime": 275.7785,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274164>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 9,
+ "stack": Array [
+ 42,
+ 42,
+ 47,
+ 47,
+ 52,
+ 52,
+ 57,
+ 57,
+ 61,
+ ],
+ "threadCPUDelta": Array [
+ 6,
+ 0,
+ 9,
+ 0,
+ 20,
+ 0,
+ 6,
+ 0,
+ 2,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ 262.732625,
+ 273.755,
+ 274.768584,
+ 285.764042,
+ 286.765084,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274164",
+ "unregisterTime": 287.756375,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274165>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 10,
+ "stack": Array [
+ 67,
+ 67,
+ 72,
+ 72,
+ 77,
+ 77,
+ 82,
+ 82,
+ 87,
+ 87,
+ ],
+ "threadCPUDelta": Array [
+ 2,
+ 0,
+ 6,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 4,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 263.723459,
+ 264.733042,
+ 274.768584,
+ 275.7785,
+ 287.756375,
+ 288.76475,
+ 299.7795,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 10,
+ 1,
+ 12,
+ 1,
+ 11,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274165",
+ "unregisterTime": 300.814417,
+ },
+ ],
+}
+`;
+
+exports[`profiler-edit tool loads a profile from a URL 1`] = `
+Object {
+ "counters": Array [],
+ "libs": Array [
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "F635824E318B3F0C842CC369737F2B680",
+ "codeId": "F635824E318B3F0C842CC369737F2B68",
+ "debugName": "dyld",
+ "debugPath": "/usr/lib/dyld",
+ "name": "dyld",
+ "path": "/usr/lib/dyld",
+ },
+ Object {
+ "arch": "arm64",
+ "breakpadId": "F61DA4D57CBB38CA8BDF059C645834520",
+ "codeId": "F61DA4D57CBB38CA8BDF059C64583452",
+ "debugName": "a.out",
+ "debugPath": "/usr/helloworld/a.out",
+ "name": "a.out",
+ "path": "/usr/helloworld/a.out",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "E03E84786F5C3D21A79A58408F5140000",
+ "codeId": "E03E84786F5C3D21A79A58408F514000",
+ "debugName": "libsystem_pthread.dylib",
+ "debugPath": "/usr/lib/system/libsystem_pthread.dylib",
+ "name": "libsystem_pthread.dylib",
+ "path": "/usr/lib/system/libsystem_pthread.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "71FF45B8F14E36669E966CF58315B91D0",
+ "codeId": "71FF45B8F14E36669E966CF58315B91D",
+ "debugName": "libsystem_kernel.dylib",
+ "debugPath": "/usr/lib/system/libsystem_kernel.dylib",
+ "name": "libsystem_kernel.dylib",
+ "path": "/usr/lib/system/libsystem_kernel.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "D30F183093D03D0B8CBA9544E84BFD5B0",
+ "codeId": "D30F183093D03D0B8CBA9544E84BFD5B",
+ "debugName": "libsystem_c.dylib",
+ "debugPath": "/usr/lib/system/libsystem_c.dylib",
+ "name": "libsystem_c.dylib",
+ "path": "/usr/lib/system/libsystem_c.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "B4BF9F8931D737428CE7AB3554F9F5250",
+ "codeId": "B4BF9F8931D737428CE7AB3554F9F525",
+ "debugName": "libsystem_platform.dylib",
+ "debugPath": "/usr/lib/system/libsystem_platform.dylib",
+ "name": "libsystem_platform.dylib",
+ "path": "/usr/lib/system/libsystem_platform.dylib",
+ },
+ ],
+ "meta": Object {
+ "categories": Array [
+ Object {
+ "color": "grey",
+ "name": "Other",
+ "subcategories": Array [
+ "Other",
+ ],
+ },
+ Object {
+ "color": "yellow",
+ "name": "User",
+ "subcategories": Array [
+ "Other",
+ ],
+ },
+ ],
+ "debug": false,
+ "extensions": Object {
+ "baseURL": Array [],
+ "id": Array [],
+ "length": 0,
+ "name": Array [],
+ },
+ "interval": 1,
+ "markerSchema": Array [],
+ "oscpu": "macOS 14.6.1",
+ "pausedRanges": Array [],
+ "preprocessedProfileVersion": 62,
+ "processType": 0,
+ "product": "a.out",
+ "sampleUnits": Object {
+ "eventDelay": "ms",
+ "threadCPUDelta": "µs",
+ "time": "ms",
+ },
+ "sourceCodeIsNotOnSearchfox": true,
+ "startTime": 1726433495880.2869,
+ "symbolicated": true,
+ "usesOnlyOneStackType": true,
+ "version": 24,
+ },
+ "pages": Array [],
+ "profilerOverhead": Array [],
+ "shared": Object {
+ "frameTable": Object {
+ "address": Array [
+ 24915,
+ 16067,
+ 38027,
+ 11180,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28575,
+ 30367,
+ 18819,
+ 16188,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ ],
+ "category": Array [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ ],
+ "column": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "func": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 11,
+ 12,
+ 14,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ ],
+ "inlineDepth": Array [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ],
+ "innerWindowID": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "length": 42,
+ "line": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "nativeSymbol": Array [
+ 0,
+ 1,
+ 4,
+ 8,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 6,
+ 7,
+ 12,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ ],
+ "subcategory": Array [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ],
+ },
+ "funcTable": Object {
+ "columnNumber": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "isJS": Array [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ ],
+ "length": 15,
+ "lineNumber": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "name": Array [
+ 21,
+ 22,
+ 25,
+ 29,
+ 26,
+ 23,
+ 24,
+ 31,
+ 32,
+ 30,
+ 15,
+ 27,
+ 28,
+ 18,
+ 33,
+ ],
+ "relevantForJS": Array [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ ],
+ "resource": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 2,
+ 1,
+ 1,
+ 4,
+ 4,
+ 3,
+ 1,
+ 2,
+ 2,
+ 2,
+ 5,
+ ],
+ "source": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ },
+ "nativeSymbols": Object {
+ "address": Array [
+ 22440,
+ 15828,
+ 15752,
+ 15644,
+ 37420,
+ 28428,
+ 30256,
+ 18740,
+ 11172,
+ 17376,
+ 54332,
+ 54412,
+ 16080,
+ ],
+ "functionSize": Array [
+ 2788,
+ 380,
+ 76,
+ 108,
+ 1028,
+ 320,
+ 120,
+ 92,
+ 44,
+ 44,
+ 80,
+ 464,
+ 212,
+ ],
+ "length": 13,
+ "libIndex": Array [
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 2,
+ 2,
+ 2,
+ 3,
+ 3,
+ 4,
+ 4,
+ 5,
+ ],
+ "name": Array [
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31,
+ 32,
+ 33,
+ ],
+ },
+ "resourceTable": Object {
+ "host": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "length": 6,
+ "lib": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ ],
+ "name": Array [
+ 4,
+ 5,
+ 6,
+ 7,
+ 14,
+ 20,
+ ],
+ "type": Array [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ ],
+ },
+ "sources": Object {
+ "filename": Array [],
+ "id": Array [],
+ "length": 0,
+ "sourceMapURL": Array [],
+ "startColumn": Array [],
+ "startLine": Array [],
+ },
+ "stackTable": Object {
+ "frame": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 12,
+ 13,
+ 14,
+ 15,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 19,
+ 20,
+ 21,
+ 22,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 31,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ ],
+ "length": 88,
+ "prefix": Array [
+ null,
+ 0,
+ 1,
+ 2,
+ null,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ null,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 11,
+ 16,
+ 17,
+ 18,
+ 19,
+ null,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 22,
+ 27,
+ 28,
+ 29,
+ 30,
+ 27,
+ 32,
+ 33,
+ 34,
+ 35,
+ null,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 38,
+ 43,
+ 44,
+ 45,
+ 46,
+ 43,
+ 48,
+ 49,
+ 50,
+ 51,
+ 48,
+ 53,
+ 54,
+ 55,
+ 56,
+ null,
+ 58,
+ 59,
+ 60,
+ null,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 63,
+ 68,
+ 69,
+ 70,
+ 71,
+ 68,
+ 73,
+ 74,
+ 75,
+ 76,
+ 73,
+ 78,
+ 79,
+ 80,
+ 81,
+ 78,
+ 83,
+ 84,
+ 85,
+ 86,
+ ],
+ },
+ "stringArray": Array [
+ "0x6153",
+ "0x3ec3",
+ "0x948b",
+ "0x2bac",
+ "dyld",
+ "a.out",
+ "libsystem_pthread.dylib",
+ "libsystem_kernel.dylib",
+ "0x6f93",
+ "0x3db3",
+ "0x3d33",
+ "0xd47f",
+ "0xd567",
+ "0x43e8",
+ "libsystem_c.dylib",
+ "0x3d67",
+ "0x6f9f",
+ "0x769f",
+ "0x4983",
+ "0x3f3c",
+ "libsystem_platform.dylib",
+ "start",
+ "main",
+ "threadfunc(void*)",
+ "fac(unsigned long)",
+ "_pthread_join",
+ "_pthread_start",
+ "_pthread_exit",
+ "_pthread_terminate_invoke",
+ "__ulock_wait",
+ "__semwait_signal",
+ "usleep",
+ "nanosleep",
+ "_platform_memset",
+ ],
+ },
+ "threads": Array [
+ Object {
+ "isMainThread": true,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "a.out",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 237.805292,
+ "samples": Object {
+ "length": 11,
+ "stack": Array [
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ ],
+ "threadCPUDelta": Array [
+ 11273,
+ 0,
+ 8,
+ 0,
+ 3,
+ 4,
+ 0,
+ 30,
+ 0,
+ 21,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ 262.732625,
+ 263.723459,
+ 274.768584,
+ 275.7785,
+ 286.765084,
+ 287.756375,
+ 299.7795,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ 1,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 12,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274156",
+ "unregisterTime": 300.814417,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274161>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 2,
+ "stack": Array [
+ 9,
+ 9,
+ ],
+ "threadCPUDelta": Array [
+ 7,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274161",
+ "unregisterTime": 252.728334,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274162>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 4,
+ "stack": Array [
+ 15,
+ 15,
+ 20,
+ 20,
+ ],
+ "threadCPUDelta": Array [
+ 3,
+ 0,
+ 5,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274162",
+ "unregisterTime": 262.732625,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274163>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 6,
+ "stack": Array [
+ 26,
+ 26,
+ 31,
+ 31,
+ 36,
+ 36,
+ ],
+ "threadCPUDelta": Array [
+ 1,
+ 0,
+ 5,
+ 0,
+ 3,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 263.723459,
+ 264.733042,
+ 274.768584,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 10,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274163",
+ "unregisterTime": 275.7785,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274164>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 9,
+ "stack": Array [
+ 42,
+ 42,
+ 47,
+ 47,
+ 52,
+ 52,
+ 57,
+ 57,
+ 61,
+ ],
+ "threadCPUDelta": Array [
+ 6,
+ 0,
+ 9,
+ 0,
+ 20,
+ 0,
+ 6,
+ 0,
+ 2,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ 262.732625,
+ 273.755,
+ 274.768584,
+ 285.764042,
+ 286.765084,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274164",
+ "unregisterTime": 287.756375,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274165>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 10,
+ "stack": Array [
+ 67,
+ 67,
+ 72,
+ 72,
+ 77,
+ 77,
+ 82,
+ 82,
+ 87,
+ 87,
+ ],
+ "threadCPUDelta": Array [
+ 2,
+ 0,
+ 6,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 4,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 263.723459,
+ 264.733042,
+ 274.768584,
+ 275.7785,
+ 287.756375,
+ 288.76475,
+ 299.7795,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 10,
+ 1,
+ 12,
+ 1,
+ 11,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274165",
+ "unregisterTime": 300.814417,
+ },
+ ],
+}
+`;
+
+exports[`profiler-edit tool loads a profile from a storage hash 1`] = `
+Object {
+ "counters": Array [],
+ "libs": Array [
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "F635824E318B3F0C842CC369737F2B680",
+ "codeId": "F635824E318B3F0C842CC369737F2B68",
+ "debugName": "dyld",
+ "debugPath": "/usr/lib/dyld",
+ "name": "dyld",
+ "path": "/usr/lib/dyld",
+ },
+ Object {
+ "arch": "arm64",
+ "breakpadId": "F61DA4D57CBB38CA8BDF059C645834520",
+ "codeId": "F61DA4D57CBB38CA8BDF059C64583452",
+ "debugName": "a.out",
+ "debugPath": "/usr/helloworld/a.out",
+ "name": "a.out",
+ "path": "/usr/helloworld/a.out",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "E03E84786F5C3D21A79A58408F5140000",
+ "codeId": "E03E84786F5C3D21A79A58408F514000",
+ "debugName": "libsystem_pthread.dylib",
+ "debugPath": "/usr/lib/system/libsystem_pthread.dylib",
+ "name": "libsystem_pthread.dylib",
+ "path": "/usr/lib/system/libsystem_pthread.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "71FF45B8F14E36669E966CF58315B91D0",
+ "codeId": "71FF45B8F14E36669E966CF58315B91D",
+ "debugName": "libsystem_kernel.dylib",
+ "debugPath": "/usr/lib/system/libsystem_kernel.dylib",
+ "name": "libsystem_kernel.dylib",
+ "path": "/usr/lib/system/libsystem_kernel.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "D30F183093D03D0B8CBA9544E84BFD5B0",
+ "codeId": "D30F183093D03D0B8CBA9544E84BFD5B",
+ "debugName": "libsystem_c.dylib",
+ "debugPath": "/usr/lib/system/libsystem_c.dylib",
+ "name": "libsystem_c.dylib",
+ "path": "/usr/lib/system/libsystem_c.dylib",
+ },
+ Object {
+ "arch": "arm64e",
+ "breakpadId": "B4BF9F8931D737428CE7AB3554F9F5250",
+ "codeId": "B4BF9F8931D737428CE7AB3554F9F525",
+ "debugName": "libsystem_platform.dylib",
+ "debugPath": "/usr/lib/system/libsystem_platform.dylib",
+ "name": "libsystem_platform.dylib",
+ "path": "/usr/lib/system/libsystem_platform.dylib",
+ },
+ ],
+ "meta": Object {
+ "categories": Array [
+ Object {
+ "color": "grey",
+ "name": "Other",
+ "subcategories": Array [
+ "Other",
+ ],
+ },
+ Object {
+ "color": "yellow",
+ "name": "User",
+ "subcategories": Array [
+ "Other",
+ ],
+ },
+ ],
+ "debug": false,
+ "extensions": Object {
+ "baseURL": Array [],
+ "id": Array [],
+ "length": 0,
+ "name": Array [],
+ },
+ "interval": 1,
+ "markerSchema": Array [],
+ "oscpu": "macOS 14.6.1",
+ "pausedRanges": Array [],
+ "preprocessedProfileVersion": 62,
+ "processType": 0,
+ "product": "a.out",
+ "sampleUnits": Object {
+ "eventDelay": "ms",
+ "threadCPUDelta": "µs",
+ "time": "ms",
+ },
+ "sourceCodeIsNotOnSearchfox": true,
+ "startTime": 1726433495880.2869,
+ "symbolicated": true,
+ "usesOnlyOneStackType": true,
+ "version": 24,
+ },
+ "pages": Array [],
+ "profilerOverhead": Array [],
+ "shared": Object {
+ "frameTable": Object {
+ "address": Array [
+ 24915,
+ 16067,
+ 38027,
+ 11180,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ 28575,
+ 30367,
+ 18819,
+ 16188,
+ 28563,
+ 15795,
+ 15667,
+ 54399,
+ 54631,
+ 17384,
+ 15719,
+ ],
+ "category": Array [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ ],
+ "column": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "func": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ 4,
+ 11,
+ 12,
+ 14,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 6,
+ ],
+ "inlineDepth": Array [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ],
+ "innerWindowID": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "length": 42,
+ "line": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "nativeSymbol": Array [
+ 0,
+ 1,
+ 4,
+ 8,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ 5,
+ 6,
+ 7,
+ 12,
+ 5,
+ 2,
+ 3,
+ 10,
+ 11,
+ 9,
+ 3,
+ ],
+ "subcategory": Array [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ],
+ },
+ "funcTable": Object {
+ "columnNumber": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "isJS": Array [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ ],
+ "length": 15,
+ "lineNumber": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "name": Array [
+ 21,
+ 22,
+ 25,
+ 29,
+ 26,
+ 23,
+ 24,
+ 31,
+ 32,
+ 30,
+ 15,
+ 27,
+ 28,
+ 18,
+ 33,
+ ],
+ "relevantForJS": Array [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ ],
+ "resource": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 2,
+ 1,
+ 1,
+ 4,
+ 4,
+ 3,
+ 1,
+ 2,
+ 2,
+ 2,
+ 5,
+ ],
+ "source": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ },
+ "nativeSymbols": Object {
+ "address": Array [
+ 22440,
+ 15828,
+ 15752,
+ 15644,
+ 37420,
+ 28428,
+ 30256,
+ 18740,
+ 11172,
+ 17376,
+ 54332,
+ 54412,
+ 16080,
+ ],
+ "functionSize": Array [
+ 2788,
+ 380,
+ 76,
+ 108,
+ 1028,
+ 320,
+ 120,
+ 92,
+ 44,
+ 44,
+ 80,
+ 464,
+ 212,
+ ],
+ "length": 13,
+ "libIndex": Array [
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 2,
+ 2,
+ 2,
+ 3,
+ 3,
+ 4,
+ 4,
+ 5,
+ ],
+ "name": Array [
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31,
+ 32,
+ 33,
+ ],
+ },
+ "resourceTable": Object {
+ "host": Array [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ ],
+ "length": 6,
+ "lib": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ ],
+ "name": Array [
+ 4,
+ 5,
+ 6,
+ 7,
+ 14,
+ 20,
+ ],
+ "type": Array [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ ],
+ },
+ "sources": Object {
+ "filename": Array [],
+ "id": Array [],
+ "length": 0,
+ "sourceMapURL": Array [],
+ "startColumn": Array [],
+ "startLine": Array [],
+ },
+ "stackTable": Object {
+ "frame": Array [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 12,
+ 13,
+ 14,
+ 15,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 19,
+ 20,
+ 21,
+ 22,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 26,
+ 27,
+ 28,
+ 29,
+ 31,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 37,
+ 38,
+ 39,
+ 40,
+ ],
+ "length": 88,
+ "prefix": Array [
+ null,
+ 0,
+ 1,
+ 2,
+ null,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ null,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 11,
+ 16,
+ 17,
+ 18,
+ 19,
+ null,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 22,
+ 27,
+ 28,
+ 29,
+ 30,
+ 27,
+ 32,
+ 33,
+ 34,
+ 35,
+ null,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 38,
+ 43,
+ 44,
+ 45,
+ 46,
+ 43,
+ 48,
+ 49,
+ 50,
+ 51,
+ 48,
+ 53,
+ 54,
+ 55,
+ 56,
+ null,
+ 58,
+ 59,
+ 60,
+ null,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 63,
+ 68,
+ 69,
+ 70,
+ 71,
+ 68,
+ 73,
+ 74,
+ 75,
+ 76,
+ 73,
+ 78,
+ 79,
+ 80,
+ 81,
+ 78,
+ 83,
+ 84,
+ 85,
+ 86,
+ ],
+ },
+ "stringArray": Array [
+ "0x6153",
+ "0x3ec3",
+ "0x948b",
+ "0x2bac",
+ "dyld",
+ "a.out",
+ "libsystem_pthread.dylib",
+ "libsystem_kernel.dylib",
+ "0x6f93",
+ "0x3db3",
+ "0x3d33",
+ "0xd47f",
+ "0xd567",
+ "0x43e8",
+ "libsystem_c.dylib",
+ "0x3d67",
+ "0x6f9f",
+ "0x769f",
+ "0x4983",
+ "0x3f3c",
+ "libsystem_platform.dylib",
+ "start",
+ "main",
+ "threadfunc(void*)",
+ "fac(unsigned long)",
+ "_pthread_join",
+ "_pthread_start",
+ "_pthread_exit",
+ "_pthread_terminate_invoke",
+ "__ulock_wait",
+ "__semwait_signal",
+ "usleep",
+ "nanosleep",
+ "_platform_memset",
+ ],
+ },
+ "threads": Array [
+ Object {
+ "isMainThread": true,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "a.out",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 237.805292,
+ "samples": Object {
+ "length": 11,
+ "stack": Array [
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ ],
+ "threadCPUDelta": Array [
+ 11273,
+ 0,
+ 8,
+ 0,
+ 3,
+ 4,
+ 0,
+ 30,
+ 0,
+ 21,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ 262.732625,
+ 263.723459,
+ 274.768584,
+ 275.7785,
+ 286.765084,
+ 287.756375,
+ 299.7795,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ 1,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 12,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274156",
+ "unregisterTime": 300.814417,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274161>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 2,
+ "stack": Array [
+ 9,
+ 9,
+ ],
+ "threadCPUDelta": Array [
+ 7,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274161",
+ "unregisterTime": 252.728334,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274162>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 4,
+ "stack": Array [
+ 15,
+ 15,
+ 20,
+ 20,
+ ],
+ "threadCPUDelta": Array [
+ 3,
+ 0,
+ 5,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274162",
+ "unregisterTime": 262.732625,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274163>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 6,
+ "stack": Array [
+ 26,
+ 26,
+ 31,
+ 31,
+ 36,
+ 36,
+ ],
+ "threadCPUDelta": Array [
+ 1,
+ 0,
+ 5,
+ 0,
+ 3,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 263.723459,
+ 264.733042,
+ 274.768584,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 10,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274163",
+ "unregisterTime": 275.7785,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274164>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 9,
+ "stack": Array [
+ 42,
+ 42,
+ 47,
+ 47,
+ 52,
+ 52,
+ 57,
+ 57,
+ 61,
+ ],
+ "threadCPUDelta": Array [
+ 6,
+ 0,
+ 9,
+ 0,
+ 20,
+ 0,
+ 6,
+ 0,
+ 2,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 261.724667,
+ 262.732625,
+ 273.755,
+ 274.768584,
+ 285.764042,
+ 286.765084,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 9,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274164",
+ "unregisterTime": 287.756375,
+ },
+ Object {
+ "isMainThread": false,
+ "markers": Object {
+ "category": Array [],
+ "data": Array [],
+ "endTime": Array [],
+ "length": 0,
+ "name": Array [],
+ "phase": Array [],
+ "startTime": Array [],
+ },
+ "name": "Thread <6274165>",
+ "pausedRanges": Array [],
+ "pid": "56127",
+ "processName": "a.out",
+ "processShutdownTime": 300.814417,
+ "processStartupTime": 237.805292,
+ "processType": "default",
+ "registerTime": 240.520375,
+ "samples": Object {
+ "length": 10,
+ "stack": Array [
+ 67,
+ 67,
+ 72,
+ 72,
+ 77,
+ 77,
+ 82,
+ 82,
+ 87,
+ 87,
+ ],
+ "threadCPUDelta": Array [
+ 2,
+ 0,
+ 6,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 4,
+ 0,
+ ],
+ "time": Array [
+ 240.520375,
+ 251.722709,
+ 252.728334,
+ 263.723459,
+ 264.733042,
+ 274.768584,
+ 275.7785,
+ 287.756375,
+ 288.76475,
+ 299.7795,
+ ],
+ "weight": Array [
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 10,
+ 1,
+ 12,
+ 1,
+ 11,
+ ],
+ "weightType": "samples",
+ },
+ "tid": "6274165",
+ "unregisterTime": 300.814417,
+ },
+ ],
+}
+`;
diff --git a/src/test/integration/profiler-edit/profiler-edit.test.ts b/src/test/integration/profiler-edit/profiler-edit.test.ts
new file mode 100644
index 0000000000..26baa85eac
--- /dev/null
+++ b/src/test/integration/profiler-edit/profiler-edit.test.ts
@@ -0,0 +1,194 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import fs from 'fs';
+import os from 'os';
+import path from 'path';
+import type { CliOptions } from '../../../node-tools/profiler-edit';
+import { run } from '../../../node-tools/profiler-edit';
+import { GOOGLE_STORAGE_BUCKET } from 'firefox-profiler/app-logic/constants';
+
+// An end-to-end test for the profiler-edit tool's symbolication feature.
+
+// Note that this test is running in a Jest environment which includes
+// various mocks / shims that makes it feel more like a browser environment.
+// For example, window.Worker is available.
+//
+// This is somewhat unfortunate because profiler-edit is intended to
+// run in vanilla Node, not in a browser, so we're not really testing
+// under realistic conditions here.
+//
+// It may be worth splitting this test off into a separate "vanilla Node"
+// testing environment at some point.
+
+describe('profiler-edit tool', function () {
+ async function runToTempFileAndReturnOutput(options: CliOptions) {
+ const tempDir = fs.mkdtempSync(
+ path.join(os.tmpdir(), 'profiler-edit-test')
+ );
+ const tempFile = path.join(tempDir, 'temp.json');
+ options.output = tempFile;
+
+ try {
+ await run(options);
+ return JSON.parse(fs.readFileSync(tempFile, 'utf-8'));
+ } finally {
+ fs.rmSync(tempDir, { recursive: true, force: true });
+ }
+ }
+
+ it('is symbolicating a trace correctly', async function () {
+ jest.spyOn(console, 'log').mockImplementation(() => {});
+ jest.spyOn(console, 'warn').mockImplementation(() => {});
+
+ const symbolsJson = fs.readFileSync(
+ 'src/test/integration/profiler-edit/symbol-server-response.json'
+ );
+
+ window.fetchMock.post(
+ 'http://symbol.server/symbolicate/v5',
+ new Response(symbolsJson as any)
+ );
+
+ const options: CliOptions = {
+ input: {
+ type: 'FILE',
+ path: 'src/test/integration/profiler-edit/unsymbolicated.json',
+ },
+ output: '',
+ symbolicateWithServer: 'http://symbol.server',
+ };
+
+ const result = await runToTempFileAndReturnOutput(options);
+
+ expect(console.warn).not.toHaveBeenCalled();
+ expect(result).toMatchSnapshot();
+ });
+
+ it('is symbolicating a .json.gz trace correctly', async function () {
+ jest.spyOn(console, 'log').mockImplementation(() => {});
+ jest.spyOn(console, 'warn').mockImplementation(() => {});
+
+ const symbolsJson = fs.readFileSync(
+ 'src/test/integration/profiler-edit/symbol-server-response.json'
+ );
+
+ window.fetchMock.post(
+ 'http://symbol.server/symbolicate/v5',
+ new Response(symbolsJson as any)
+ );
+
+ const options: CliOptions = {
+ input: {
+ type: 'FILE',
+ path: 'src/test/integration/profiler-edit/unsymbolicated.json.gz',
+ },
+ output: '',
+ symbolicateWithServer: 'http://symbol.server',
+ };
+
+ const result = await runToTempFileAndReturnOutput(options);
+
+ expect(console.warn).not.toHaveBeenCalled();
+ expect(result).toMatchSnapshot();
+ });
+
+ it('writes gzip-compressed output when the output filename ends with .gz', async function () {
+ jest.spyOn(console, 'log').mockImplementation(() => {});
+ jest.spyOn(console, 'warn').mockImplementation(() => {});
+
+ const tempDir = fs.mkdtempSync(
+ path.join(os.tmpdir(), 'profiler-edit-test')
+ );
+ const tempFile = path.join(tempDir, 'out.json.gz');
+
+ try {
+ const options: CliOptions = {
+ input: {
+ type: 'FILE',
+ path: 'src/test/integration/profiler-edit/unsymbolicated.json',
+ },
+ output: tempFile,
+ };
+
+ await run(options);
+
+ const bytes = fs.readFileSync(tempFile);
+ expect(bytes[0]).toBe(0x1f);
+ expect(bytes[1]).toBe(0x8b);
+ } finally {
+ fs.rmSync(tempDir, { recursive: true, force: true });
+ }
+ });
+
+ it('loads a profile from a URL', async function () {
+ jest.spyOn(console, 'log').mockImplementation(() => {});
+ jest.spyOn(console, 'warn').mockImplementation(() => {});
+
+ const profileJson = fs.readFileSync(
+ 'src/test/integration/profiler-edit/unsymbolicated.json'
+ );
+ const symbolsJson = fs.readFileSync(
+ 'src/test/integration/profiler-edit/symbol-server-response.json'
+ );
+
+ window.fetchMock.get(
+ 'http://example.profile/profile.json',
+ new Response(profileJson as any)
+ );
+ window.fetchMock.post(
+ 'http://symbol.server/symbolicate/v5',
+ new Response(symbolsJson as any)
+ );
+
+ const options: CliOptions = {
+ input: {
+ type: 'URL',
+ url: 'http://example.profile/profile.json',
+ },
+ output: '',
+ symbolicateWithServer: 'http://symbol.server',
+ };
+
+ const result = await runToTempFileAndReturnOutput(options);
+
+ expect(console.warn).not.toHaveBeenCalled();
+ expect(result).toMatchSnapshot();
+ });
+
+ it('loads a profile from a storage hash', async function () {
+ jest.spyOn(console, 'log').mockImplementation(() => {});
+ jest.spyOn(console, 'warn').mockImplementation(() => {});
+
+ const profileJson = fs.readFileSync(
+ 'src/test/integration/profiler-edit/unsymbolicated.json'
+ );
+ const symbolsJson = fs.readFileSync(
+ 'src/test/integration/profiler-edit/symbol-server-response.json'
+ );
+
+ const hash = 'testHash123';
+ window.fetchMock.get(
+ `https://storage.googleapis.com/${GOOGLE_STORAGE_BUCKET}/${hash}`,
+ new Response(profileJson as any)
+ );
+ window.fetchMock.post(
+ 'http://symbol.server/symbolicate/v5',
+ new Response(symbolsJson as any)
+ );
+
+ const options: CliOptions = {
+ input: {
+ type: 'HASH',
+ hash,
+ },
+ output: '',
+ symbolicateWithServer: 'http://symbol.server',
+ };
+
+ const result = await runToTempFileAndReturnOutput(options);
+
+ expect(console.warn).not.toHaveBeenCalled();
+ expect(result).toMatchSnapshot();
+ });
+});
diff --git a/src/test/integration/symbolicator-cli/symbol-server-response.json b/src/test/integration/profiler-edit/symbol-server-response.json
similarity index 100%
rename from src/test/integration/symbolicator-cli/symbol-server-response.json
rename to src/test/integration/profiler-edit/symbol-server-response.json
diff --git a/src/test/integration/symbolicator-cli/unsymbolicated.json b/src/test/integration/profiler-edit/unsymbolicated.json
similarity index 100%
rename from src/test/integration/symbolicator-cli/unsymbolicated.json
rename to src/test/integration/profiler-edit/unsymbolicated.json
diff --git a/src/test/integration/symbolicator-cli/unsymbolicated.json.gz b/src/test/integration/profiler-edit/unsymbolicated.json.gz
similarity index 100%
rename from src/test/integration/symbolicator-cli/unsymbolicated.json.gz
rename to src/test/integration/profiler-edit/unsymbolicated.json.gz
diff --git a/src/test/integration/symbolicator-cli/__snapshots__/symbolicator-cli.test.ts.snap b/src/test/integration/symbolicator-cli/__snapshots__/symbolicator-cli.test.ts.snap
deleted file mode 100644
index 19dd70789f..0000000000
--- a/src/test/integration/symbolicator-cli/__snapshots__/symbolicator-cli.test.ts.snap
+++ /dev/null
@@ -1,2657 +0,0 @@
-// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
-
-exports[`symbolicator-cli tool is symbolicating a .json.gz trace correctly 1`] = `
-Object {
- "counters": Array [],
- "libs": Array [
- Object {
- "arch": "arm64e",
- "breakpadId": "F635824E318B3F0C842CC369737F2B680",
- "codeId": "F635824E318B3F0C842CC369737F2B68",
- "debugName": "dyld",
- "debugPath": "/usr/lib/dyld",
- "name": "dyld",
- "path": "/usr/lib/dyld",
- },
- Object {
- "arch": "arm64",
- "breakpadId": "F61DA4D57CBB38CA8BDF059C645834520",
- "codeId": "F61DA4D57CBB38CA8BDF059C64583452",
- "debugName": "a.out",
- "debugPath": "/usr/helloworld/a.out",
- "name": "a.out",
- "path": "/usr/helloworld/a.out",
- },
- Object {
- "arch": "arm64e",
- "breakpadId": "E03E84786F5C3D21A79A58408F5140000",
- "codeId": "E03E84786F5C3D21A79A58408F514000",
- "debugName": "libsystem_pthread.dylib",
- "debugPath": "/usr/lib/system/libsystem_pthread.dylib",
- "name": "libsystem_pthread.dylib",
- "path": "/usr/lib/system/libsystem_pthread.dylib",
- },
- Object {
- "arch": "arm64e",
- "breakpadId": "71FF45B8F14E36669E966CF58315B91D0",
- "codeId": "71FF45B8F14E36669E966CF58315B91D",
- "debugName": "libsystem_kernel.dylib",
- "debugPath": "/usr/lib/system/libsystem_kernel.dylib",
- "name": "libsystem_kernel.dylib",
- "path": "/usr/lib/system/libsystem_kernel.dylib",
- },
- Object {
- "arch": "arm64e",
- "breakpadId": "D30F183093D03D0B8CBA9544E84BFD5B0",
- "codeId": "D30F183093D03D0B8CBA9544E84BFD5B",
- "debugName": "libsystem_c.dylib",
- "debugPath": "/usr/lib/system/libsystem_c.dylib",
- "name": "libsystem_c.dylib",
- "path": "/usr/lib/system/libsystem_c.dylib",
- },
- Object {
- "arch": "arm64e",
- "breakpadId": "B4BF9F8931D737428CE7AB3554F9F5250",
- "codeId": "B4BF9F8931D737428CE7AB3554F9F525",
- "debugName": "libsystem_platform.dylib",
- "debugPath": "/usr/lib/system/libsystem_platform.dylib",
- "name": "libsystem_platform.dylib",
- "path": "/usr/lib/system/libsystem_platform.dylib",
- },
- ],
- "meta": Object {
- "categories": Array [
- Object {
- "color": "grey",
- "name": "Other",
- "subcategories": Array [
- "Other",
- ],
- },
- Object {
- "color": "yellow",
- "name": "User",
- "subcategories": Array [
- "Other",
- ],
- },
- ],
- "debug": false,
- "extensions": Object {
- "baseURL": Array [],
- "id": Array [],
- "length": 0,
- "name": Array [],
- },
- "interval": 1,
- "markerSchema": Array [],
- "oscpu": "macOS 14.6.1",
- "pausedRanges": Array [],
- "preprocessedProfileVersion": 61,
- "processType": 0,
- "product": "a.out",
- "sampleUnits": Object {
- "eventDelay": "ms",
- "threadCPUDelta": "µs",
- "time": "ms",
- },
- "sourceCodeIsNotOnSearchfox": true,
- "startTime": 1726433495880.2869,
- "symbolicated": true,
- "usesOnlyOneStackType": true,
- "version": 24,
- },
- "pages": Array [],
- "profilerOverhead": Array [],
- "shared": Object {
- "frameTable": Object {
- "address": Array [
- 24915,
- 16067,
- 38027,
- 11180,
- 28563,
- 15795,
- 15667,
- 54399,
- 54631,
- 17384,
- 28563,
- 15795,
- 15667,
- 54399,
- 54631,
- 17384,
- 15719,
- 28563,
- 15795,
- 15667,
- 54399,
- 54631,
- 17384,
- 15719,
- 28563,
- 15795,
- 15667,
- 54399,
- 54631,
- 17384,
- 15719,
- 28575,
- 30367,
- 18819,
- 16188,
- 28563,
- 15795,
- 15667,
- 54399,
- 54631,
- 17384,
- 15719,
- ],
- "category": Array [
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- ],
- "column": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "func": Array [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 6,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 6,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 6,
- 4,
- 11,
- 12,
- 14,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 6,
- ],
- "inlineDepth": Array [
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- ],
- "innerWindowID": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "length": 42,
- "line": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "nativeSymbol": Array [
- 0,
- 1,
- 4,
- 8,
- 5,
- 2,
- 3,
- 10,
- 11,
- 9,
- 5,
- 2,
- 3,
- 10,
- 11,
- 9,
- 3,
- 5,
- 2,
- 3,
- 10,
- 11,
- 9,
- 3,
- 5,
- 2,
- 3,
- 10,
- 11,
- 9,
- 3,
- 5,
- 6,
- 7,
- 12,
- 5,
- 2,
- 3,
- 10,
- 11,
- 9,
- 3,
- ],
- "subcategory": Array [
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- ],
- },
- "funcTable": Object {
- "columnNumber": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "isJS": Array [
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- ],
- "length": 15,
- "lineNumber": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "name": Array [
- 21,
- 22,
- 25,
- 29,
- 26,
- 23,
- 24,
- 31,
- 32,
- 30,
- 15,
- 27,
- 28,
- 18,
- 33,
- ],
- "relevantForJS": Array [
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- ],
- "resource": Array [
- 0,
- 1,
- 2,
- 3,
- 2,
- 1,
- 1,
- 4,
- 4,
- 3,
- 1,
- 2,
- 2,
- 2,
- 5,
- ],
- "source": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- },
- "nativeSymbols": Object {
- "address": Array [
- 22440,
- 15828,
- 15752,
- 15644,
- 37420,
- 28428,
- 30256,
- 18740,
- 11172,
- 17376,
- 54332,
- 54412,
- 16080,
- ],
- "functionSize": Array [
- 2788,
- 380,
- 76,
- 108,
- 1028,
- 320,
- 120,
- 92,
- 44,
- 44,
- 80,
- 464,
- 212,
- ],
- "length": 13,
- "libIndex": Array [
- 0,
- 1,
- 1,
- 1,
- 2,
- 2,
- 2,
- 2,
- 3,
- 3,
- 4,
- 4,
- 5,
- ],
- "name": Array [
- 21,
- 22,
- 23,
- 24,
- 25,
- 26,
- 27,
- 28,
- 29,
- 30,
- 31,
- 32,
- 33,
- ],
- },
- "resourceTable": Object {
- "host": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "length": 6,
- "lib": Array [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- ],
- "name": Array [
- 4,
- 5,
- 6,
- 7,
- 14,
- 20,
- ],
- "type": Array [
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- ],
- },
- "sources": Object {
- "filename": Array [],
- "id": Array [],
- "length": 0,
- "sourceMapURL": Array [],
- "startColumn": Array [],
- "startLine": Array [],
- },
- "stackTable": Object {
- "frame": Array [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 16,
- 12,
- 13,
- 14,
- 15,
- 17,
- 18,
- 19,
- 20,
- 21,
- 22,
- 23,
- 19,
- 20,
- 21,
- 22,
- 23,
- 19,
- 20,
- 21,
- 22,
- 24,
- 25,
- 26,
- 27,
- 28,
- 29,
- 30,
- 26,
- 27,
- 28,
- 29,
- 30,
- 26,
- 27,
- 28,
- 29,
- 30,
- 26,
- 27,
- 28,
- 29,
- 31,
- 32,
- 33,
- 34,
- 35,
- 36,
- 37,
- 38,
- 39,
- 40,
- 41,
- 37,
- 38,
- 39,
- 40,
- 41,
- 37,
- 38,
- 39,
- 40,
- 41,
- 37,
- 38,
- 39,
- 40,
- 41,
- 37,
- 38,
- 39,
- 40,
- ],
- "length": 88,
- "prefix": Array [
- null,
- 0,
- 1,
- 2,
- null,
- 4,
- 5,
- 6,
- 7,
- 8,
- null,
- 10,
- 11,
- 12,
- 13,
- 14,
- 11,
- 16,
- 17,
- 18,
- 19,
- null,
- 21,
- 22,
- 23,
- 24,
- 25,
- 22,
- 27,
- 28,
- 29,
- 30,
- 27,
- 32,
- 33,
- 34,
- 35,
- null,
- 37,
- 38,
- 39,
- 40,
- 41,
- 38,
- 43,
- 44,
- 45,
- 46,
- 43,
- 48,
- 49,
- 50,
- 51,
- 48,
- 53,
- 54,
- 55,
- 56,
- null,
- 58,
- 59,
- 60,
- null,
- 62,
- 63,
- 64,
- 65,
- 66,
- 63,
- 68,
- 69,
- 70,
- 71,
- 68,
- 73,
- 74,
- 75,
- 76,
- 73,
- 78,
- 79,
- 80,
- 81,
- 78,
- 83,
- 84,
- 85,
- 86,
- ],
- },
- "stringArray": Array [
- "0x6153",
- "0x3ec3",
- "0x948b",
- "0x2bac",
- "dyld",
- "a.out",
- "libsystem_pthread.dylib",
- "libsystem_kernel.dylib",
- "0x6f93",
- "0x3db3",
- "0x3d33",
- "0xd47f",
- "0xd567",
- "0x43e8",
- "libsystem_c.dylib",
- "0x3d67",
- "0x6f9f",
- "0x769f",
- "0x4983",
- "0x3f3c",
- "libsystem_platform.dylib",
- "start",
- "main",
- "threadfunc(void*)",
- "fac(unsigned long)",
- "_pthread_join",
- "_pthread_start",
- "_pthread_exit",
- "_pthread_terminate_invoke",
- "__ulock_wait",
- "__semwait_signal",
- "usleep",
- "nanosleep",
- "_platform_memset",
- ],
- },
- "threads": Array [
- Object {
- "isMainThread": true,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "a.out",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 237.805292,
- "samples": Object {
- "length": 11,
- "stack": Array [
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- ],
- "threadCPUDelta": Array [
- 11273,
- 0,
- 8,
- 0,
- 3,
- 4,
- 0,
- 30,
- 0,
- 21,
- 0,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- 252.728334,
- 261.724667,
- 262.732625,
- 263.723459,
- 274.768584,
- 275.7785,
- 286.765084,
- 287.756375,
- 299.7795,
- ],
- "weight": Array [
- 1,
- 11,
- 1,
- 9,
- 1,
- 1,
- 11,
- 1,
- 11,
- 1,
- 12,
- ],
- "weightType": "samples",
- },
- "tid": "6274156",
- "unregisterTime": 300.814417,
- },
- Object {
- "isMainThread": false,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "Thread <6274161>",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 240.520375,
- "samples": Object {
- "length": 2,
- "stack": Array [
- 9,
- 9,
- ],
- "threadCPUDelta": Array [
- 7,
- 0,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- ],
- "weight": Array [
- 1,
- 11,
- ],
- "weightType": "samples",
- },
- "tid": "6274161",
- "unregisterTime": 252.728334,
- },
- Object {
- "isMainThread": false,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "Thread <6274162>",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 240.520375,
- "samples": Object {
- "length": 4,
- "stack": Array [
- 15,
- 15,
- 20,
- 20,
- ],
- "threadCPUDelta": Array [
- 3,
- 0,
- 5,
- 0,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- 252.728334,
- 261.724667,
- ],
- "weight": Array [
- 1,
- 11,
- 1,
- 9,
- ],
- "weightType": "samples",
- },
- "tid": "6274162",
- "unregisterTime": 262.732625,
- },
- Object {
- "isMainThread": false,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "Thread <6274163>",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 240.520375,
- "samples": Object {
- "length": 6,
- "stack": Array [
- 26,
- 26,
- 31,
- 31,
- 36,
- 36,
- ],
- "threadCPUDelta": Array [
- 1,
- 0,
- 5,
- 0,
- 3,
- 0,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- 252.728334,
- 263.723459,
- 264.733042,
- 274.768584,
- ],
- "weight": Array [
- 1,
- 11,
- 1,
- 11,
- 1,
- 10,
- ],
- "weightType": "samples",
- },
- "tid": "6274163",
- "unregisterTime": 275.7785,
- },
- Object {
- "isMainThread": false,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "Thread <6274164>",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 240.520375,
- "samples": Object {
- "length": 9,
- "stack": Array [
- 42,
- 42,
- 47,
- 47,
- 52,
- 52,
- 57,
- 57,
- 61,
- ],
- "threadCPUDelta": Array [
- 6,
- 0,
- 9,
- 0,
- 20,
- 0,
- 6,
- 0,
- 2,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- 252.728334,
- 261.724667,
- 262.732625,
- 273.755,
- 274.768584,
- 285.764042,
- 286.765084,
- ],
- "weight": Array [
- 1,
- 11,
- 1,
- 9,
- 1,
- 11,
- 1,
- 11,
- 1,
- ],
- "weightType": "samples",
- },
- "tid": "6274164",
- "unregisterTime": 287.756375,
- },
- Object {
- "isMainThread": false,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "Thread <6274165>",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 240.520375,
- "samples": Object {
- "length": 10,
- "stack": Array [
- 67,
- 67,
- 72,
- 72,
- 77,
- 77,
- 82,
- 82,
- 87,
- 87,
- ],
- "threadCPUDelta": Array [
- 2,
- 0,
- 6,
- 0,
- 4,
- 0,
- 5,
- 0,
- 4,
- 0,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- 252.728334,
- 263.723459,
- 264.733042,
- 274.768584,
- 275.7785,
- 287.756375,
- 288.76475,
- 299.7795,
- ],
- "weight": Array [
- 1,
- 11,
- 1,
- 11,
- 1,
- 10,
- 1,
- 12,
- 1,
- 11,
- ],
- "weightType": "samples",
- },
- "tid": "6274165",
- "unregisterTime": 300.814417,
- },
- ],
-}
-`;
-
-exports[`symbolicator-cli tool is symbolicating a trace correctly 1`] = `
-Object {
- "counters": Array [],
- "libs": Array [
- Object {
- "arch": "arm64e",
- "breakpadId": "F635824E318B3F0C842CC369737F2B680",
- "codeId": "F635824E318B3F0C842CC369737F2B68",
- "debugName": "dyld",
- "debugPath": "/usr/lib/dyld",
- "name": "dyld",
- "path": "/usr/lib/dyld",
- },
- Object {
- "arch": "arm64",
- "breakpadId": "F61DA4D57CBB38CA8BDF059C645834520",
- "codeId": "F61DA4D57CBB38CA8BDF059C64583452",
- "debugName": "a.out",
- "debugPath": "/usr/helloworld/a.out",
- "name": "a.out",
- "path": "/usr/helloworld/a.out",
- },
- Object {
- "arch": "arm64e",
- "breakpadId": "E03E84786F5C3D21A79A58408F5140000",
- "codeId": "E03E84786F5C3D21A79A58408F514000",
- "debugName": "libsystem_pthread.dylib",
- "debugPath": "/usr/lib/system/libsystem_pthread.dylib",
- "name": "libsystem_pthread.dylib",
- "path": "/usr/lib/system/libsystem_pthread.dylib",
- },
- Object {
- "arch": "arm64e",
- "breakpadId": "71FF45B8F14E36669E966CF58315B91D0",
- "codeId": "71FF45B8F14E36669E966CF58315B91D",
- "debugName": "libsystem_kernel.dylib",
- "debugPath": "/usr/lib/system/libsystem_kernel.dylib",
- "name": "libsystem_kernel.dylib",
- "path": "/usr/lib/system/libsystem_kernel.dylib",
- },
- Object {
- "arch": "arm64e",
- "breakpadId": "D30F183093D03D0B8CBA9544E84BFD5B0",
- "codeId": "D30F183093D03D0B8CBA9544E84BFD5B",
- "debugName": "libsystem_c.dylib",
- "debugPath": "/usr/lib/system/libsystem_c.dylib",
- "name": "libsystem_c.dylib",
- "path": "/usr/lib/system/libsystem_c.dylib",
- },
- Object {
- "arch": "arm64e",
- "breakpadId": "B4BF9F8931D737428CE7AB3554F9F5250",
- "codeId": "B4BF9F8931D737428CE7AB3554F9F525",
- "debugName": "libsystem_platform.dylib",
- "debugPath": "/usr/lib/system/libsystem_platform.dylib",
- "name": "libsystem_platform.dylib",
- "path": "/usr/lib/system/libsystem_platform.dylib",
- },
- ],
- "meta": Object {
- "categories": Array [
- Object {
- "color": "grey",
- "name": "Other",
- "subcategories": Array [
- "Other",
- ],
- },
- Object {
- "color": "yellow",
- "name": "User",
- "subcategories": Array [
- "Other",
- ],
- },
- ],
- "debug": false,
- "extensions": Object {
- "baseURL": Array [],
- "id": Array [],
- "length": 0,
- "name": Array [],
- },
- "interval": 1,
- "markerSchema": Array [],
- "oscpu": "macOS 14.6.1",
- "pausedRanges": Array [],
- "preprocessedProfileVersion": 61,
- "processType": 0,
- "product": "a.out",
- "sampleUnits": Object {
- "eventDelay": "ms",
- "threadCPUDelta": "µs",
- "time": "ms",
- },
- "sourceCodeIsNotOnSearchfox": true,
- "startTime": 1726433495880.2869,
- "symbolicated": true,
- "usesOnlyOneStackType": true,
- "version": 24,
- },
- "pages": Array [],
- "profilerOverhead": Array [],
- "shared": Object {
- "frameTable": Object {
- "address": Array [
- 24915,
- 16067,
- 38027,
- 11180,
- 28563,
- 15795,
- 15667,
- 54399,
- 54631,
- 17384,
- 28563,
- 15795,
- 15667,
- 54399,
- 54631,
- 17384,
- 15719,
- 28563,
- 15795,
- 15667,
- 54399,
- 54631,
- 17384,
- 15719,
- 28563,
- 15795,
- 15667,
- 54399,
- 54631,
- 17384,
- 15719,
- 28575,
- 30367,
- 18819,
- 16188,
- 28563,
- 15795,
- 15667,
- 54399,
- 54631,
- 17384,
- 15719,
- ],
- "category": Array [
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- ],
- "column": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "func": Array [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 6,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 6,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 6,
- 4,
- 11,
- 12,
- 14,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 6,
- ],
- "inlineDepth": Array [
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- ],
- "innerWindowID": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "length": 42,
- "line": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "nativeSymbol": Array [
- 0,
- 1,
- 4,
- 8,
- 5,
- 2,
- 3,
- 10,
- 11,
- 9,
- 5,
- 2,
- 3,
- 10,
- 11,
- 9,
- 3,
- 5,
- 2,
- 3,
- 10,
- 11,
- 9,
- 3,
- 5,
- 2,
- 3,
- 10,
- 11,
- 9,
- 3,
- 5,
- 6,
- 7,
- 12,
- 5,
- 2,
- 3,
- 10,
- 11,
- 9,
- 3,
- ],
- "subcategory": Array [
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- ],
- },
- "funcTable": Object {
- "columnNumber": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "isJS": Array [
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- ],
- "length": 15,
- "lineNumber": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "name": Array [
- 21,
- 22,
- 25,
- 29,
- 26,
- 23,
- 24,
- 31,
- 32,
- 30,
- 15,
- 27,
- 28,
- 18,
- 33,
- ],
- "relevantForJS": Array [
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- ],
- "resource": Array [
- 0,
- 1,
- 2,
- 3,
- 2,
- 1,
- 1,
- 4,
- 4,
- 3,
- 1,
- 2,
- 2,
- 2,
- 5,
- ],
- "source": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- },
- "nativeSymbols": Object {
- "address": Array [
- 22440,
- 15828,
- 15752,
- 15644,
- 37420,
- 28428,
- 30256,
- 18740,
- 11172,
- 17376,
- 54332,
- 54412,
- 16080,
- ],
- "functionSize": Array [
- 2788,
- 380,
- 76,
- 108,
- 1028,
- 320,
- 120,
- 92,
- 44,
- 44,
- 80,
- 464,
- 212,
- ],
- "length": 13,
- "libIndex": Array [
- 0,
- 1,
- 1,
- 1,
- 2,
- 2,
- 2,
- 2,
- 3,
- 3,
- 4,
- 4,
- 5,
- ],
- "name": Array [
- 21,
- 22,
- 23,
- 24,
- 25,
- 26,
- 27,
- 28,
- 29,
- 30,
- 31,
- 32,
- 33,
- ],
- },
- "resourceTable": Object {
- "host": Array [
- null,
- null,
- null,
- null,
- null,
- null,
- ],
- "length": 6,
- "lib": Array [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- ],
- "name": Array [
- 4,
- 5,
- 6,
- 7,
- 14,
- 20,
- ],
- "type": Array [
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- ],
- },
- "sources": Object {
- "filename": Array [],
- "id": Array [],
- "length": 0,
- "sourceMapURL": Array [],
- "startColumn": Array [],
- "startLine": Array [],
- },
- "stackTable": Object {
- "frame": Array [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 16,
- 12,
- 13,
- 14,
- 15,
- 17,
- 18,
- 19,
- 20,
- 21,
- 22,
- 23,
- 19,
- 20,
- 21,
- 22,
- 23,
- 19,
- 20,
- 21,
- 22,
- 24,
- 25,
- 26,
- 27,
- 28,
- 29,
- 30,
- 26,
- 27,
- 28,
- 29,
- 30,
- 26,
- 27,
- 28,
- 29,
- 30,
- 26,
- 27,
- 28,
- 29,
- 31,
- 32,
- 33,
- 34,
- 35,
- 36,
- 37,
- 38,
- 39,
- 40,
- 41,
- 37,
- 38,
- 39,
- 40,
- 41,
- 37,
- 38,
- 39,
- 40,
- 41,
- 37,
- 38,
- 39,
- 40,
- 41,
- 37,
- 38,
- 39,
- 40,
- ],
- "length": 88,
- "prefix": Array [
- null,
- 0,
- 1,
- 2,
- null,
- 4,
- 5,
- 6,
- 7,
- 8,
- null,
- 10,
- 11,
- 12,
- 13,
- 14,
- 11,
- 16,
- 17,
- 18,
- 19,
- null,
- 21,
- 22,
- 23,
- 24,
- 25,
- 22,
- 27,
- 28,
- 29,
- 30,
- 27,
- 32,
- 33,
- 34,
- 35,
- null,
- 37,
- 38,
- 39,
- 40,
- 41,
- 38,
- 43,
- 44,
- 45,
- 46,
- 43,
- 48,
- 49,
- 50,
- 51,
- 48,
- 53,
- 54,
- 55,
- 56,
- null,
- 58,
- 59,
- 60,
- null,
- 62,
- 63,
- 64,
- 65,
- 66,
- 63,
- 68,
- 69,
- 70,
- 71,
- 68,
- 73,
- 74,
- 75,
- 76,
- 73,
- 78,
- 79,
- 80,
- 81,
- 78,
- 83,
- 84,
- 85,
- 86,
- ],
- },
- "stringArray": Array [
- "0x6153",
- "0x3ec3",
- "0x948b",
- "0x2bac",
- "dyld",
- "a.out",
- "libsystem_pthread.dylib",
- "libsystem_kernel.dylib",
- "0x6f93",
- "0x3db3",
- "0x3d33",
- "0xd47f",
- "0xd567",
- "0x43e8",
- "libsystem_c.dylib",
- "0x3d67",
- "0x6f9f",
- "0x769f",
- "0x4983",
- "0x3f3c",
- "libsystem_platform.dylib",
- "start",
- "main",
- "threadfunc(void*)",
- "fac(unsigned long)",
- "_pthread_join",
- "_pthread_start",
- "_pthread_exit",
- "_pthread_terminate_invoke",
- "__ulock_wait",
- "__semwait_signal",
- "usleep",
- "nanosleep",
- "_platform_memset",
- ],
- },
- "threads": Array [
- Object {
- "isMainThread": true,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "a.out",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 237.805292,
- "samples": Object {
- "length": 11,
- "stack": Array [
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- ],
- "threadCPUDelta": Array [
- 11273,
- 0,
- 8,
- 0,
- 3,
- 4,
- 0,
- 30,
- 0,
- 21,
- 0,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- 252.728334,
- 261.724667,
- 262.732625,
- 263.723459,
- 274.768584,
- 275.7785,
- 286.765084,
- 287.756375,
- 299.7795,
- ],
- "weight": Array [
- 1,
- 11,
- 1,
- 9,
- 1,
- 1,
- 11,
- 1,
- 11,
- 1,
- 12,
- ],
- "weightType": "samples",
- },
- "tid": "6274156",
- "unregisterTime": 300.814417,
- },
- Object {
- "isMainThread": false,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "Thread <6274161>",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 240.520375,
- "samples": Object {
- "length": 2,
- "stack": Array [
- 9,
- 9,
- ],
- "threadCPUDelta": Array [
- 7,
- 0,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- ],
- "weight": Array [
- 1,
- 11,
- ],
- "weightType": "samples",
- },
- "tid": "6274161",
- "unregisterTime": 252.728334,
- },
- Object {
- "isMainThread": false,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "Thread <6274162>",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 240.520375,
- "samples": Object {
- "length": 4,
- "stack": Array [
- 15,
- 15,
- 20,
- 20,
- ],
- "threadCPUDelta": Array [
- 3,
- 0,
- 5,
- 0,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- 252.728334,
- 261.724667,
- ],
- "weight": Array [
- 1,
- 11,
- 1,
- 9,
- ],
- "weightType": "samples",
- },
- "tid": "6274162",
- "unregisterTime": 262.732625,
- },
- Object {
- "isMainThread": false,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "Thread <6274163>",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 240.520375,
- "samples": Object {
- "length": 6,
- "stack": Array [
- 26,
- 26,
- 31,
- 31,
- 36,
- 36,
- ],
- "threadCPUDelta": Array [
- 1,
- 0,
- 5,
- 0,
- 3,
- 0,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- 252.728334,
- 263.723459,
- 264.733042,
- 274.768584,
- ],
- "weight": Array [
- 1,
- 11,
- 1,
- 11,
- 1,
- 10,
- ],
- "weightType": "samples",
- },
- "tid": "6274163",
- "unregisterTime": 275.7785,
- },
- Object {
- "isMainThread": false,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "Thread <6274164>",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 240.520375,
- "samples": Object {
- "length": 9,
- "stack": Array [
- 42,
- 42,
- 47,
- 47,
- 52,
- 52,
- 57,
- 57,
- 61,
- ],
- "threadCPUDelta": Array [
- 6,
- 0,
- 9,
- 0,
- 20,
- 0,
- 6,
- 0,
- 2,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- 252.728334,
- 261.724667,
- 262.732625,
- 273.755,
- 274.768584,
- 285.764042,
- 286.765084,
- ],
- "weight": Array [
- 1,
- 11,
- 1,
- 9,
- 1,
- 11,
- 1,
- 11,
- 1,
- ],
- "weightType": "samples",
- },
- "tid": "6274164",
- "unregisterTime": 287.756375,
- },
- Object {
- "isMainThread": false,
- "markers": Object {
- "category": Array [],
- "data": Array [],
- "endTime": Array [],
- "length": 0,
- "name": Array [],
- "phase": Array [],
- "startTime": Array [],
- },
- "name": "Thread <6274165>",
- "pausedRanges": Array [],
- "pid": "56127",
- "processName": "a.out",
- "processShutdownTime": 300.814417,
- "processStartupTime": 237.805292,
- "processType": "default",
- "registerTime": 240.520375,
- "samples": Object {
- "length": 10,
- "stack": Array [
- 67,
- 67,
- 72,
- 72,
- 77,
- 77,
- 82,
- 82,
- 87,
- 87,
- ],
- "threadCPUDelta": Array [
- 2,
- 0,
- 6,
- 0,
- 4,
- 0,
- 5,
- 0,
- 4,
- 0,
- ],
- "time": Array [
- 240.520375,
- 251.722709,
- 252.728334,
- 263.723459,
- 264.733042,
- 274.768584,
- 275.7785,
- 287.756375,
- 288.76475,
- 299.7795,
- ],
- "weight": Array [
- 1,
- 11,
- 1,
- 11,
- 1,
- 10,
- 1,
- 12,
- 1,
- 11,
- ],
- "weightType": "samples",
- },
- "tid": "6274165",
- "unregisterTime": 300.814417,
- },
- ],
-}
-`;
diff --git a/src/test/integration/symbolicator-cli/symbolicator-cli.test.ts b/src/test/integration/symbolicator-cli/symbolicator-cli.test.ts
deleted file mode 100644
index c0dd627b79..0000000000
--- a/src/test/integration/symbolicator-cli/symbolicator-cli.test.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-import fs from 'fs';
-import os from 'os';
-import path from 'path';
-import type { CliOptions } from '../../../symbolicator-cli';
-import { run } from '../../../symbolicator-cli';
-
-// An end-to-end test for the symbolicator-cli tool.
-
-// Note that this test is running in a Jest environment which includes
-// various mocks / shims that makes it feel more like a browser environment.
-// For example, window.Worker is available.
-//
-// This is somewhat unfortunate because symbolicator-cli is intended to
-// run in vanilla Node, not in a browser, so we're not really testing
-// under realistic conditions here.
-//
-// It may be worth splitting this test off into a separate "vanilla Node"
-// testing environment at some point.
-
-describe('symbolicator-cli tool', function () {
- async function runToTempFileAndReturnOutput(options: CliOptions) {
- const tempDir = fs.mkdtempSync(
- path.join(os.tmpdir(), 'symbolicator-cli-test')
- );
- const tempFile = path.join(tempDir, 'temp.json');
- options.output = tempFile;
-
- try {
- await run(options);
- return JSON.parse(fs.readFileSync(tempFile, 'utf-8'));
- } finally {
- fs.rmSync(tempDir, { recursive: true, force: true });
- }
- }
-
- it('is symbolicating a trace correctly', async function () {
- jest.spyOn(console, 'log').mockImplementation(() => {});
- jest.spyOn(console, 'warn').mockImplementation(() => {});
-
- const symbolsJson = fs.readFileSync(
- 'src/test/integration/symbolicator-cli/symbol-server-response.json'
- );
-
- window.fetchMock.post(
- 'http://symbol.server/symbolicate/v5',
- new Response(symbolsJson as any)
- );
-
- const options = {
- input: 'src/test/integration/symbolicator-cli/unsymbolicated.json',
- output: '',
- server: 'http://symbol.server',
- };
-
- const result = await runToTempFileAndReturnOutput(options);
-
- expect(console.warn).not.toHaveBeenCalled();
- expect(result).toMatchSnapshot();
- });
-
- it('is symbolicating a .json.gz trace correctly', async function () {
- jest.spyOn(console, 'log').mockImplementation(() => {});
- jest.spyOn(console, 'warn').mockImplementation(() => {});
-
- const symbolsJson = fs.readFileSync(
- 'src/test/integration/symbolicator-cli/symbol-server-response.json'
- );
-
- window.fetchMock.post(
- 'http://symbol.server/symbolicate/v5',
- new Response(symbolsJson as any)
- );
-
- const options = {
- input: 'src/test/integration/symbolicator-cli/unsymbolicated.json.gz',
- output: '',
- server: 'http://symbol.server',
- };
-
- const result = await runToTempFileAndReturnOutput(options);
-
- expect(console.warn).not.toHaveBeenCalled();
- expect(result).toMatchSnapshot();
- });
-});
diff --git a/src/test/store/__snapshots__/profile-view.test.ts.snap b/src/test/store/__snapshots__/profile-view.test.ts.snap
index f04baf9582..9f9343610e 100644
--- a/src/test/store/__snapshots__/profile-view.test.ts.snap
+++ b/src/test/store/__snapshots__/profile-view.test.ts.snap
@@ -418,7 +418,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Firefox",
"sourceURL": "",
diff --git a/src/test/store/__snapshots__/receive-profile.test.ts.snap b/src/test/store/__snapshots__/receive-profile.test.ts.snap
index ac9c30b543..02c2f06f5a 100644
--- a/src/test/store/__snapshots__/receive-profile.test.ts.snap
+++ b/src/test/store/__snapshots__/receive-profile.test.ts.snap
@@ -1,305 +1,5 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
-exports[`actions/receive-profile _fetchProfile fails if a bad profile JSON is passed in 1`] = `[Error: The profile’s JSON could not be decoded. The full error information has been printed out to the DevTool’s console.]`;
-
-exports[`actions/receive-profile _fetchProfile fails if a bad profile JSON is passed in 2`] = `
-Array [
- Array [
- "The profile’s JSON could not be decoded.",
- ],
- Array [
- "JSON parsing error:",
- [SyntaxError: Unexpected token 'i', "invalid" is not valid JSON],
- ],
- Array [
- "Fetch response:",
- Response {
- Symbol(state): Object {
- "aborted": false,
- "body": Object {
- "length": 7,
- "source": Uint8Array [],
- "stream": ReadableStream {
- Symbol(kType): "ReadableStream",
- Symbol(kState): Object {
- "controller": ReadableByteStreamController {
- Symbol(kType): "ReadableByteStreamController",
- Symbol(kState): Object {
- "autoAllocateChunkSize": undefined,
- "byobRequest": null,
- "cancelAlgorithm": undefined,
- "closeRequested": false,
- "highWaterMark": 0,
- "pendingPullIntos": Array [],
- "pullAgain": false,
- "pullAlgorithm": undefined,
- "pulling": false,
- "queue": Array [],
- "queueTotalSize": 0,
- "started": true,
- "stream": [Circular],
- },
- },
- "disturbed": true,
- "reader": ReadableStreamDefaultReader {
- Symbol(kType): "ReadableStreamDefaultReader",
- Symbol(kState): Object {
- "close": Object {
- "promise": Promise {},
- "reject": [Function],
- "resolve": [Function],
- },
- "readRequests": Array [],
- "stream": [Circular],
- },
- },
- "state": "closed",
- "storedError": undefined,
- "transfer": Object {
- "port1": undefined,
- "port2": undefined,
- "promise": undefined,
- "writable": undefined,
- },
- },
- Symbol(nodejs.webstream.isClosedPromise): Object {
- "promise": Promise {},
- "reject": [Function],
- "resolve": [Function],
- },
- Symbol(nodejs.webstream.controllerErrorFunction): [Function],
- },
- },
- "cacheState": "",
- "headersList": HeadersList {
- "cookies": null,
- Symbol(headers map): Map {
- "content-length" => Object {
- "name": "content-length",
- "value": "7",
- },
- "content-type" => Object {
- "name": "content-type",
- "value": "application/json",
- },
- },
- Symbol(headers map sorted): null,
- },
- "rangeRequested": false,
- "requestIncludesCredentials": false,
- "status": 200,
- "statusText": "OK",
- "timingAllowPassed": false,
- "timingInfo": null,
- "type": "default",
- "urlList": Array [],
- },
- Symbol(headers): Headers {},
- },
- ],
-]
-`;
-
-exports[`actions/receive-profile _fetchProfile fails if a bad profile JSON is passed in, with no content type 1`] = `[Error: The profile’s JSON could not be decoded. The full error information has been printed out to the DevTool’s console.]`;
-
-exports[`actions/receive-profile _fetchProfile fails if a bad profile JSON is passed in, with no content type 2`] = `
-Array [
- Array [
- "The profile’s JSON could not be decoded.",
- ],
- Array [
- "JSON parsing error:",
- [SyntaxError: Unexpected token 'i', "invalid" is not valid JSON],
- ],
- Array [
- "Fetch response:",
- Response {
- Symbol(state): Object {
- "aborted": false,
- "body": Object {
- "length": 7,
- "source": Uint8Array [],
- "stream": ReadableStream {
- Symbol(kType): "ReadableStream",
- Symbol(kState): Object {
- "controller": ReadableByteStreamController {
- Symbol(kType): "ReadableByteStreamController",
- Symbol(kState): Object {
- "autoAllocateChunkSize": undefined,
- "byobRequest": null,
- "cancelAlgorithm": undefined,
- "closeRequested": false,
- "highWaterMark": 0,
- "pendingPullIntos": Array [],
- "pullAgain": false,
- "pullAlgorithm": undefined,
- "pulling": false,
- "queue": Array [],
- "queueTotalSize": 0,
- "started": true,
- "stream": [Circular],
- },
- },
- "disturbed": true,
- "reader": ReadableStreamDefaultReader {
- Symbol(kType): "ReadableStreamDefaultReader",
- Symbol(kState): Object {
- "close": Object {
- "promise": Promise {},
- "reject": [Function],
- "resolve": [Function],
- },
- "readRequests": Array [],
- "stream": [Circular],
- },
- },
- "state": "closed",
- "storedError": undefined,
- "transfer": Object {
- "port1": undefined,
- "port2": undefined,
- "promise": undefined,
- "writable": undefined,
- },
- },
- Symbol(nodejs.webstream.isClosedPromise): Object {
- "promise": Promise {},
- "reject": [Function],
- "resolve": [Function],
- },
- Symbol(nodejs.webstream.controllerErrorFunction): [Function],
- },
- },
- "cacheState": "",
- "headersList": HeadersList {
- "cookies": null,
- Symbol(headers map): Map {
- "content-length" => Object {
- "name": "content-length",
- "value": "7",
- },
- "content-type" => Object {
- "name": "content-type",
- "value": "undefined",
- },
- },
- Symbol(headers map sorted): null,
- },
- "rangeRequested": false,
- "requestIncludesCredentials": false,
- "status": 200,
- "statusText": "OK",
- "timingAllowPassed": false,
- "timingInfo": null,
- "type": "default",
- "urlList": Array [],
- },
- Symbol(headers): Headers {},
- },
- ],
-]
-`;
-
-exports[`actions/receive-profile _fetchProfile fails if a bad zip file is passed in 1`] = `[Error: Unable to open the archive file. The full error information has been printed out to the DevTool’s console.]`;
-
-exports[`actions/receive-profile _fetchProfile fails if a bad zip file is passed in 2`] = `
-Array [
- Array [
- "Unable to open the archive file.",
- ],
- Array [
- "Error:",
- [Error: Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html],
- ],
- Array [
- "Fetch response:",
- Response {
- Symbol(state): Object {
- "aborted": false,
- "body": Object {
- "length": 4,
- "source": Uint8Array [],
- "stream": ReadableStream {
- Symbol(kType): "ReadableStream",
- Symbol(kState): Object {
- "controller": ReadableByteStreamController {
- Symbol(kType): "ReadableByteStreamController",
- Symbol(kState): Object {
- "autoAllocateChunkSize": undefined,
- "byobRequest": null,
- "cancelAlgorithm": undefined,
- "closeRequested": false,
- "highWaterMark": 0,
- "pendingPullIntos": Array [],
- "pullAgain": false,
- "pullAlgorithm": undefined,
- "pulling": false,
- "queue": Array [],
- "queueTotalSize": 0,
- "started": true,
- "stream": [Circular],
- },
- },
- "disturbed": true,
- "reader": ReadableStreamDefaultReader {
- Symbol(kType): "ReadableStreamDefaultReader",
- Symbol(kState): Object {
- "close": Object {
- "promise": Promise {},
- "reject": [Function],
- "resolve": [Function],
- },
- "readRequests": Array [],
- "stream": [Circular],
- },
- },
- "state": "closed",
- "storedError": undefined,
- "transfer": Object {
- "port1": undefined,
- "port2": undefined,
- "promise": undefined,
- "writable": undefined,
- },
- },
- Symbol(nodejs.webstream.isClosedPromise): Object {
- "promise": Promise {},
- "reject": [Function],
- "resolve": [Function],
- },
- Symbol(nodejs.webstream.controllerErrorFunction): [Function],
- },
- },
- "cacheState": "",
- "headersList": HeadersList {
- "cookies": null,
- Symbol(headers map): Map {
- "content-length" => Object {
- "name": "content-length",
- "value": "4",
- },
- "content-type" => Object {
- "name": "content-type",
- "value": "application/zip",
- },
- },
- Symbol(headers map sorted): null,
- },
- "rangeRequested": false,
- "requestIncludesCredentials": false,
- "status": 200,
- "statusText": "OK",
- "timingAllowPassed": false,
- "timingInfo": null,
- "type": "default",
- "urlList": Array [],
- },
- Symbol(headers): Headers {},
- },
- ],
-]
-`;
-
exports[`actions/receive-profile retrieveProfileFromFile will be an error to view a profile with no threads 1`] = `"No threads were captured in this profile, there is nothing to display."`;
exports[`actions/receive-profile retrieveProfileFromFile will give an error when unable to decompress a zipped profile 1`] = `[Error: Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html]`;
diff --git a/src/test/store/app.test.ts b/src/test/store/app.test.ts
index 1ff0040aab..42542a8787 100644
--- a/src/test/store/app.test.ts
+++ b/src/test/store/app.test.ts
@@ -1,13 +1,11 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-import { storeWithSimpleProfile, storeWithProfile } from '../fixtures/stores';
+import { storeWithSimpleProfile } from '../fixtures/stores';
import * as UrlStateSelectors from '../../selectors/url-state';
import * as AppSelectors from '../../selectors/app';
import createStore from '../../app-logic/create-store';
import { withAnalyticsMock } from '../fixtures/mocks/analytics';
-import { isolateProcess } from '../../actions/profile-view';
-import { getProfileWithNiceTracks } from '../fixtures/profiles/tracks';
import * as AppActions from '../../actions/app';
@@ -148,31 +146,4 @@ describe('app actions', function () {
expect(UrlStateSelectors.getSelectedTab(getState())).toEqual('calltree');
});
});
-
- describe('panelLayoutGeneration', function () {
- it('can be manually updated using an action', function () {
- const { dispatch, getState } = storeWithSimpleProfile();
- expect(AppSelectors.getPanelLayoutGeneration(getState())).toBe(0);
- dispatch(AppActions.invalidatePanelLayout());
- expect(AppSelectors.getPanelLayoutGeneration(getState())).toBe(1);
- dispatch(AppActions.invalidatePanelLayout());
- expect(AppSelectors.getPanelLayoutGeneration(getState())).toBe(2);
- });
-
- it('will be updated when working with the sidebar', function () {
- const { dispatch, getState } = storeWithSimpleProfile();
- expect(AppSelectors.getPanelLayoutGeneration(getState())).toBe(0);
- dispatch(AppActions.changeSidebarOpenState('flame-graph', false));
- expect(AppSelectors.getPanelLayoutGeneration(getState())).toBe(1);
- });
-
- it('will be updated when working with the timeline', function () {
- const { dispatch, getState } = storeWithProfile(
- getProfileWithNiceTracks()
- );
- expect(AppSelectors.getPanelLayoutGeneration(getState())).toBe(0);
- dispatch(isolateProcess(0));
- expect(AppSelectors.getPanelLayoutGeneration(getState())).toBe(1);
- });
- });
});
diff --git a/src/test/store/profile-view.test.ts b/src/test/store/profile-view.test.ts
index 8d530c8758..2b830e08c5 100644
--- a/src/test/store/profile-view.test.ts
+++ b/src/test/store/profile-view.test.ts
@@ -48,6 +48,7 @@ import {
type BreakdownByCategory,
} from '../../profile-logic/profile-data';
import { getSelfAndTotalForCallNode } from '../../profile-logic/call-tree';
+import { checkBit } from '../../utils/bitset';
import type {
TrackReference,
@@ -511,8 +512,8 @@ describe('actions/ProfileView', function () {
store.getState(),
memoryTrackReference
);
- if (memoryTrack.type !== 'memory') {
- throw new Error('Expected to get memory track.');
+ if (memoryTrack.type !== 'counter') {
+ throw new Error('Expected to get counter track.');
}
}
@@ -838,8 +839,8 @@ describe('actions/ProfileView', function () {
' - C (total: 1, self: —)',
' - D (total: 1, self: 1)',
' - E (total: 1, self: 1)',
- '- D (total: 1, self: 1)',
'- C (total: 1, self: 1)',
+ '- D (total: 1, self: 1)',
]);
});
@@ -922,6 +923,91 @@ describe('actions/ProfileView', function () {
});
});
+ /**
+ * Covers the bitset returned by `getSearchFilteredFuncMatchesBitSet`, which
+ * the stack chart uses to dim non-matching nodes. The stack filter above
+ * only exercises whether each stack is kept; these tests pin down the
+ * per-func match semantics across name, filename, and library fields, and
+ * the OR semantics when multiple search strings are provided.
+ */
+ describe('getSearchFilteredFuncMatchesBitSet', function () {
+ // Each func's three searchable fields (name, resource/lib, filename) use
+ // distinct prefixes ("fn", "rs", "sc") and a unique per-func index, so
+ // every search string used below appears in exactly one field on exactly
+ // one func. That lets us assert unambiguously which field triggered a
+ // match.
+ function setup() {
+ const {
+ profile,
+ funcNamesPerThread: [funcNames],
+ } = getProfileFromTextSamples(`
+ fn1[lib:rs1][file:sc1] fn2[lib:rs2][file:sc2] fn3[lib:rs3][file:sc3]
+ fn4[lib:rs4][file:sc4]
+ `);
+ const { dispatch, getState } = storeWithProfile(profile);
+ return { dispatch, getState, funcNames };
+ }
+
+ function getMatchingFuncNames(
+ getState: () => any,
+ funcNames: string[]
+ ): string[] {
+ const bitSet =
+ selectedThreadSelectors.getSearchFilteredFuncMatchesBitSet(getState());
+ if (bitSet === null) {
+ return [];
+ }
+ const matched: string[] = [];
+ for (let i = 0; i < funcNames.length; i++) {
+ if (checkBit(bitSet, i)) {
+ matched.push(funcNames[i]);
+ }
+ }
+ return matched.sort();
+ }
+
+ it('returns null when there is no active search', function () {
+ const { getState } = setup();
+ expect(
+ selectedThreadSelectors.getSearchFilteredFuncMatchesBitSet(getState())
+ ).toBeNull();
+ });
+
+ it('matches a single func by its name', function () {
+ const { dispatch, getState, funcNames } = setup();
+ dispatch(ProfileView.changeCallTreeSearchString('fn1'));
+ expect(getMatchingFuncNames(getState, funcNames)).toEqual(['fn1']);
+ });
+
+ it('matches a func by its filename', function () {
+ const { dispatch, getState, funcNames } = setup();
+ // sc2 is only set on fn2.
+ dispatch(ProfileView.changeCallTreeSearchString('sc2'));
+ expect(getMatchingFuncNames(getState, funcNames)).toEqual(['fn2']);
+ });
+
+ it('matches a func by its resource/library name', function () {
+ const { dispatch, getState, funcNames } = setup();
+ // rs3 is only set on fn3. Match is case-insensitive.
+ dispatch(ProfileView.changeCallTreeSearchString('RS3'));
+ expect(getMatchingFuncNames(getState, funcNames)).toEqual(['fn3']);
+ });
+
+ it('matches every func matching any of several search strings (OR)', function () {
+ const { dispatch, getState, funcNames } = setup();
+ // "fn1" matches only func fn1; "fn3" matches only func fn3.
+ dispatch(ProfileView.changeCallTreeSearchString('fn1,fn3'));
+ expect(getMatchingFuncNames(getState, funcNames)).toEqual(['fn1', 'fn3']);
+ });
+
+ it('combines matches across different fields with OR', function () {
+ const { dispatch, getState, funcNames } = setup();
+ // "sc1" matches fn1 by filename; "rs4" matches fn4 by lib name.
+ dispatch(ProfileView.changeCallTreeSearchString('sc1,rs4'));
+ expect(getMatchingFuncNames(getState, funcNames)).toEqual(['fn1', 'fn4']);
+ });
+ });
+
/**
* This test is more involved on checking for correctness compared to the other
* tests, which are more for asserting their simple getter/setter types of behavior.
@@ -1629,6 +1715,78 @@ describe('actions/ProfileView', function () {
});
});
+ describe('changeIncludeIdleSamples', function () {
+ function setup() {
+ // Four samples: two with an Idle leaf, two with a non-idle leaf.
+ const { profile } = getProfileFromTextSamples(`
+ A A A A
+ B[cat:DOM] B[cat:Idle] B[cat:DOM] B[cat:Idle]
+ `);
+ return storeWithProfile(profile);
+ }
+
+ it('defaults to true and toggles through the reducer', function () {
+ const { dispatch, getState } = setup();
+
+ expect(UrlStateSelectors.getIncludeIdleSamples(getState())).toEqual(true);
+ dispatch(ProfileView.changeIncludeIdleSamples(false));
+ expect(UrlStateSelectors.getIncludeIdleSamples(getState())).toEqual(
+ false
+ );
+ });
+
+ it('nulls out stacks of samples whose leaf frame is idle when off', function () {
+ const { dispatch, getState } = setup();
+
+ const beforeThread =
+ selectedThreadSelectors.getFilteredThread(getState());
+ expect(beforeThread.samples.stack.every((s) => s !== null)).toBe(true);
+
+ dispatch(ProfileView.changeIncludeIdleSamples(false));
+
+ const afterThread = selectedThreadSelectors.getFilteredThread(getState());
+ const idleCategoryIndex = ensureExists(
+ ProfileViewSelectors.getIdleCategoryIndex(getState()),
+ 'Expected the test profile to have an Idle category'
+ );
+
+ // Samples 0 and 2 have DOM leaves; 1 and 3 have Idle leaves.
+ expect(afterThread.samples.stack[0]).not.toBe(null);
+ expect(afterThread.samples.stack[1]).toBe(null);
+ expect(afterThread.samples.stack[2]).not.toBe(null);
+ expect(afterThread.samples.stack[3]).toBe(null);
+
+ // The stackTable is untouched. Only sample.stack entries are nulled.
+ expect(afterThread.stackTable).toBe(beforeThread.stackTable);
+ // The kept samples still point at a stack whose category is not idle.
+ const keptStackCategories = afterThread.samples.stack
+ .filter((s): s is number => s !== null)
+ .map((s) => afterThread.stackTable.category[s]);
+ expect(keptStackCategories).not.toContain(idleCategoryIndex);
+ });
+
+ it('is a no-op when the profile has no idle category', function () {
+ const { profile } = getProfileFromTextSamples(`
+ A A
+ B[cat:DOM] B[cat:DOM]
+ `);
+ // Replace categories with a set that has no "Idle" entry.
+ profile.meta.categories = [
+ { name: 'Other', color: 'grey', subcategories: ['Other'] },
+ { name: 'DOM', color: 'blue', subcategories: ['Other'] },
+ ];
+ const { dispatch, getState } = storeWithProfile(profile);
+
+ expect(ProfileViewSelectors.getIdleCategoryIndex(getState())).toBe(null);
+
+ const before = selectedThreadSelectors.getFilteredThread(getState());
+ dispatch(ProfileView.changeIncludeIdleSamples(false));
+ const after = selectedThreadSelectors.getFilteredThread(getState());
+ // Without an idle category there is nothing to filter.
+ expect(after).toBe(before);
+ });
+ });
+
describe('updatePreviewSelection', function () {
it('updates the profile selection', function () {
const { profile } = getProfileFromTextSamples('A');
@@ -3869,12 +4027,14 @@ describe('timeline type', function () {
);
});
- it('should use the category view when cpu is not provided', () => {
+ it('should use the cpu-category view even if no cpu is provided', () => {
const { profile } = getProfileFromTextSamples('A');
// Load the store after mutating the profile.
const { getState } = storeWithProfile(profile);
- expect(UrlStateSelectors.getTimelineType(getState())).toEqual('category');
+ expect(UrlStateSelectors.getTimelineType(getState())).toEqual(
+ 'cpu-category'
+ );
});
it('should use the stack height view when category and cpu is not provided', () => {
diff --git a/src/test/store/receive-profile.test.ts b/src/test/store/receive-profile.test.ts
index 0b336a05d8..08fa5b3601 100644
--- a/src/test/store/receive-profile.test.ts
+++ b/src/test/store/receive-profile.test.ts
@@ -27,9 +27,9 @@ import {
retrieveProfileOrZipFromUrl,
retrieveProfileFromFile,
retrieveProfilesToCompare,
- _fetchProfile,
retrieveProfileForRawUrl,
} from '../../actions/receive-profile';
+import { fetchProfile as _fetchProfile } from '../../utils/profile-fetch';
import { SymbolsNotFoundError } from '../../profile-logic/errors';
import { createGeckoProfile } from '../fixtures/profiles/gecko-profile';
@@ -46,7 +46,7 @@ import {
getProfileWithThreadCPUDelta,
} from '../fixtures/profiles/processed-profile';
import { getHumanReadableTracks } from '../fixtures/profiles/tracks';
-import { waitUntilState } from '../fixtures/utils';
+import { waitUntilState, extractArrayBuffer } from '../fixtures/utils';
import { dataUrlToBytes } from 'firefox-profiler/utils/base64';
import { compress } from '../../utils/gz';
@@ -88,22 +88,6 @@ function simulateSymbolStoreHasNoCache() {
}));
}
-// Returns an ArrayBuffer which contains only the bytes that
-// are covered by the Uint8Array, making a copy if needed.
-function extractArrayBuffer(bufferView: Uint8Array): ArrayBuffer {
- if (
- bufferView.byteOffset === 0 &&
- bufferView.byteLength === bufferView.buffer.byteLength
- ) {
- return bufferView.buffer;
- }
-
- // There was extra data at the start or at the end. Make a copy.
- const copy = new Uint8Array(bufferView.byteLength);
- copy.set(bufferView);
- return copy.buffer;
-}
-
describe('actions/receive-profile', function () {
beforeEach(() => {
// The SymbolStore requires the use of IndexedDB, ensure that it exists so that
@@ -1150,193 +1134,6 @@ describe('actions/receive-profile', function () {
});
});
- /**
- * _fetchProfile is a helper function for the actions, but it is tested separately
- * since it has a decent amount of complexity around different issues with loading
- * in different support URL formats. It's mainly testing what happens when JSON
- * and zip file is sent, and what happens when things fail.
- */
- describe('_fetchProfile', function () {
- /**
- * This helper function encapsulates various configurations for the type of content
- * as well and response headers.
- */
- async function configureFetch(obj: {
- url: string;
- contentType?: string;
- content: 'generated-zip' | 'generated-json' | Uint8Array;
- }) {
- const { url, contentType, content } = obj;
- const stringProfile = serializeProfile(_getSimpleProfile());
- const profile = JSON.parse(stringProfile);
- let arrayBuffer;
-
- switch (content) {
- case 'generated-zip': {
- const zip = new JSZip();
- zip.file('profile.json', stringProfile);
- arrayBuffer = await zip.generateAsync({ type: 'uint8array' });
- break;
- }
- case 'generated-json':
- arrayBuffer = encode(stringProfile);
- break;
- default:
- arrayBuffer = content;
- break;
- }
-
- window.fetchMock.catch(403).get(url, {
- body: arrayBuffer,
- headers: {
- 'content-type': contentType,
- },
- });
-
- const reportError = jest.fn();
- const args = {
- url,
- onTemporaryError: () => {},
- reportError,
- };
-
- // Return fetch's args, based on the inputs.
- return { profile, args, reportError };
- }
-
- it('fetches a normal profile with the correct content-type headers', async function () {
- const { profile, args } = await configureFetch({
- url: 'https://example.com/profile.json',
- contentType: 'application/json',
- content: 'generated-json',
- });
-
- const profileOrZip = await _fetchProfile(args);
- expect(profileOrZip).toEqual({ responseType: 'PROFILE', profile });
- });
-
- it('fetches a zipped profile with correct content-type headers', async function () {
- const { args, reportError } = await configureFetch({
- url: 'https://example.com/profile.zip',
- contentType: 'application/zip',
- content: 'generated-zip',
- });
-
- const profileOrZip = await _fetchProfile(args);
- expect(profileOrZip.responseType).toBe('ZIP');
- expect(reportError.mock.calls.length).toBe(0);
- });
-
- it('fetches a zipped profile with incorrect content-type headers, but .zip extension', async function () {
- const { args, reportError } = await configureFetch({
- url: 'https://example.com/profile.zip',
- content: 'generated-zip',
- });
-
- const profileOrZip = await _fetchProfile(args);
- expect(profileOrZip.responseType).toBe('ZIP');
- expect(reportError.mock.calls.length).toBe(0);
- });
-
- it('fetches a profile with incorrect content-type headers, but .json extension', async function () {
- const { profile, args, reportError } = await configureFetch({
- url: 'https://example.com/profile.json',
- content: 'generated-json',
- });
-
- const profileOrZip = await _fetchProfile(args);
- expect(profileOrZip).toEqual({ responseType: 'PROFILE', profile });
- expect(reportError.mock.calls.length).toBe(0);
- });
-
- it('fetches a profile with incorrect content-type headers, no known extension, and attempts to JSON parse it it', async function () {
- const { profile, args, reportError } = await configureFetch({
- url: 'https://example.com/profile.file',
- content: 'generated-json',
- });
-
- const profileOrZip = await _fetchProfile(args);
- expect(profileOrZip).toEqual({ responseType: 'PROFILE', profile });
- expect(reportError.mock.calls.length).toBe(0);
- });
-
- it('fails if a bad zip file is passed in', async function () {
- const { args, reportError } = await configureFetch({
- url: 'https://example.com/profile.file',
- contentType: 'application/zip',
- content: new Uint8Array([0, 1, 2, 3]),
- });
-
- let userFacingError;
- try {
- await _fetchProfile(args);
- } catch (error) {
- userFacingError = error;
- }
- expect(userFacingError).toMatchSnapshot();
- expect(reportError.mock.calls.length).toBeGreaterThan(0);
- expect(reportError.mock.calls).toMatchSnapshot();
- });
-
- it('fails if a bad profile JSON is passed in', async function () {
- const invalidJSON = 'invalid';
- const { args, reportError } = await configureFetch({
- url: 'https://example.com/profile.json',
- contentType: 'application/json',
- content: encode(invalidJSON),
- });
-
- let userFacingError;
- try {
- await _fetchProfile(args);
- } catch (error) {
- userFacingError = error;
- }
- expect(userFacingError).toMatchSnapshot();
- expect(reportError.mock.calls.length).toBeGreaterThan(0);
- expect(reportError.mock.calls).toMatchSnapshot();
- });
-
- it('fails if a bad profile JSON is passed in, with no content type', async function () {
- const invalidJSON = 'invalid';
- const { args, reportError } = await configureFetch({
- url: 'https://example.com/profile.json',
- content: encode(invalidJSON),
- });
-
- let userFacingError;
- try {
- await _fetchProfile(args);
- } catch (error) {
- userFacingError = error;
- }
- expect(userFacingError).toMatchSnapshot();
- expect(reportError.mock.calls.length).toBeGreaterThan(0);
- expect(reportError.mock.calls).toMatchSnapshot();
- });
-
- it('fallback behavior if a completely unknown file is passed in', async function () {
- const invalidJSON = 'invalid';
- const profile = encode(invalidJSON);
- const { args } = await configureFetch({
- url: 'https://example.com/profile.unknown',
- content: profile,
- });
-
- let userFacingError = null;
- try {
- const profileOrZip = await _fetchProfile(args);
- expect(profileOrZip).toEqual({
- responseType: 'PROFILE',
- profile: extractArrayBuffer(profile),
- });
- } catch (error) {
- userFacingError = error;
- }
- expect(userFacingError).toBeNull();
- });
- });
-
describe('retrieveProfileFromFile', function () {
/**
* Bypass all of Flow's checks, and mock out the file interface.
diff --git a/src/test/store/symbolication.test.ts b/src/test/store/symbolication.test.ts
index 372bdd5980..81771af3ea 100644
--- a/src/test/store/symbolication.test.ts
+++ b/src/test/store/symbolication.test.ts
@@ -7,6 +7,7 @@ import { getProfileFromTextSamples } from '../fixtures/profiles/processed-profil
import {
completeSymbolTable,
partialSymbolTable,
+ jitDumpSymbolTable,
} from '../fixtures/example-symbol-table';
import type { ExampleSymbolTable } from '../fixtures/example-symbol-table';
import type { MarkerPayload } from 'firefox-profiler/types';
@@ -29,6 +30,7 @@ import { doSymbolicateProfile } from '../../actions/receive-profile';
import {
changeSelectedCallNode,
changeExpandedCallNodes,
+ changeImplementationFilter,
} from '../../actions/profile-view';
import { formatTree, formatStack } from '../fixtures/utils';
import { assertSetContainsOnly } from '../fixtures/custom-assertions';
@@ -44,18 +46,17 @@ import { SymbolsNotFoundError } from '../../profile-logic/errors';
*/
describe('doSymbolicateProfile', function () {
// Initialize a store, an unsymbolicated profile, and helper functions.
- function init() {
+ function init(profile = _createUnsymbolicatedProfile()) {
// The rejection in `requestSymbolsFromServer` outputs an error log, let's
// silence it here. The fact that we call it is tested in
// symbol-store.test.js.
jest.spyOn(console, 'log').mockImplementation(() => {});
- const profile = _createUnsymbolicatedProfile();
const store = storeWithProfile(profile);
- let symbolTable = completeSymbolTable;
+ let firefoxSymbolTable = completeSymbolTable;
function switchSymbolTable(otherSymbolTable: ExampleSymbolTable) {
- symbolTable = otherSymbolTable;
+ firefoxSymbolTable = otherSymbolTable;
}
let symbolicationProviderMode: 'from-server' | 'from-browser' =
'from-browser';
@@ -67,12 +68,19 @@ describe('doSymbolicateProfile', function () {
requestSymbolsFromServer: async (requests: LibSymbolicationRequest[]) =>
requests.map((request) => {
const { lib, addresses } = request;
- if (lib.debugName !== 'firefox.pdb') {
+
+ const symbolTables: Partial> = {
+ 'firefox.pdb': firefoxSymbolTable,
+ 'jit-52344.dump': jitDumpSymbolTable,
+ };
+
+ const symbolTable = symbolTables[lib.debugName];
+ if (symbolTable === undefined) {
return {
type: 'ERROR' as const,
request,
error: new SymbolsNotFoundError(
- 'Should only have lib called firefox.pdb',
+ `Lib name ${lib.debugName} is not in the list of known names: ${Object.keys(symbolTables).join(', ')}`,
lib
),
};
@@ -123,7 +131,7 @@ describe('doSymbolicateProfile', function () {
}
return readSymbolsFromSymbolTable(
addresses,
- symbolTable.asTuple,
+ firefoxSymbolTable.asTuple,
(s: string) => s
);
},
@@ -239,8 +247,8 @@ describe('doSymbolicateProfile', function () {
' - second symbol (total: 1, self: —)',
' - last symbol (total: 1, self: 1)',
' - last symbol (total: 1, self: 1)',
- '- third symbol (total: 1, self: 1)',
'- second symbol (total: 1, self: 1)',
+ '- third symbol (total: 1, self: 1)',
]);
const thread = getThread(getState());
@@ -251,7 +259,9 @@ describe('doSymbolicateProfile', function () {
// Helper function to get filename from source index
const getFileName = (funcIndex: number): string | null => {
const sourceIndex = funcTable.source[funcIndex];
- if (sourceIndex === null) return null;
+ if (sourceIndex === null) {
+ return null;
+ }
const urlIndex = sources.filename[sourceIndex];
return stringTable.getString(urlIndex);
};
@@ -473,8 +483,30 @@ describe('doSymbolicateProfile', function () {
' - second symbol (total: 1, self: —)',
' - last symbol (total: 1, self: 1)',
' - last symbol (total: 1, self: 1)',
- '- third symbol (total: 1, self: 1)',
'- second symbol (total: 1, self: 1)',
+ '- third symbol (total: 1, self: 1)',
+ ]);
+ });
+
+ it('inline frames for JS functions appear in the JS-only call tree after symbolication', async () => {
+ const {
+ store: { dispatch, getState },
+ profile,
+ symbolStore,
+ switchSymbolProviderMode,
+ } = init(_createUnsymbolicatedJitProfile());
+
+ switchSymbolProviderMode('from-server');
+
+ await doSymbolicateProfile(dispatch, profile, symbolStore);
+
+ // Check that the `useState.js` node shows up in the JS-only call tree.
+ // This function is an inline frame from the jitdump symbol info.
+ dispatch(changeImplementationFilter('js'));
+ expect(formatTree(getCallTree(getState()))).toEqual([
+ '- renderButton.js (total: 1, self: —)',
+ ' - useState.js (total: 1, self: 1)',
+ '- runJobs.js (total: 1, self: 1)',
]);
});
@@ -555,8 +587,8 @@ describe('doSymbolicateProfile', function () {
' - second symbol (total: 1, self: —)',
' - last symbol (total: 1, self: 1)',
' - last symbol (total: 1, self: 1)',
- '- third symbol (total: 1, self: 1)',
'- second symbol (total: 1, self: 1)',
+ '- third symbol (total: 1, self: 1)',
]);
});
});
@@ -623,3 +655,11 @@ function _createUnsymbolicatedProfile() {
return profile;
}
+
+function _createUnsymbolicatedJitProfile() {
+ // See jitDumpSyms (in example-symbol-table.ts) for the corresponding symbols.
+ const { profile } = getProfileFromTextSamples(`
+ renderButton.js[lib:jit-52344.dump][address:a] runJobs.js[lib:jit-52344.dump][address:2000]
+ `);
+ return profile;
+}
diff --git a/src/test/store/zipped-profiles.test.ts b/src/test/store/zipped-profiles.test.ts
index aceee2a398..19db955c36 100644
--- a/src/test/store/zipped-profiles.test.ts
+++ b/src/test/store/zipped-profiles.test.ts
@@ -15,6 +15,9 @@ import JSZip from 'jszip';
import * as ZippedProfilesActions from '../../actions/zipped-profiles';
import * as ReceiveProfileActions from '../../actions/receive-profile';
import * as ProfileViewActions from '../../actions/profile-view';
+import { getProfileFromTextSamples } from '../fixtures/profiles/processed-profile';
+import { serializeProfile } from '../../profile-logic/process-profile';
+import { compress } from '../../utils/gz';
import type { PreviewSelection } from 'firefox-profiler/types';
describe('reducer zipFileState', function () {
@@ -101,6 +104,33 @@ describe('reducer zipFileState', function () {
});
});
+ it('can load a gzipped profile from a zip file', async function () {
+ const store = createStore();
+ const { getState, dispatch } = store;
+ const { profile } = getProfileFromTextSamples('A');
+ // Re-wrap in this realm's Uint8Array: the worker-backed `compress`
+ // returns a typed array whose `instanceof Uint8Array` check fails against
+ // the main realm's global, so JSZip wouldn't recognize it directly.
+ const gzippedProfile = new Uint8Array(
+ await compress(serializeProfile(profile))
+ );
+
+ const zip = new JSZip();
+ zip.file('profile.json.gz', gzippedProfile);
+ const zipBytes = await zip.generateAsync({ type: 'uint8array' });
+ const loadedZip = await JSZip.loadAsync(zipBytes);
+ dispatch(ReceiveProfileActions.receiveZipFile(loadedZip));
+
+ await dispatch(
+ ZippedProfilesActions.viewProfileFromPathInZipFile('profile.json.gz')
+ );
+
+ expect(ZippedProfilesSelectors.getZipFileState(getState()).phase).toBe(
+ 'VIEW_PROFILE_IN_ZIP_FILE'
+ );
+ expect(ProfileViewSelectors.getProfile(getState())).toBeTruthy();
+ });
+
it('will fail when trying to load an invalid profile', async function () {
const store = createStore();
const { getState, dispatch } = store;
diff --git a/src/test/unit/__snapshots__/profile-conversion.test.ts.snap b/src/test/unit/__snapshots__/profile-conversion.test.ts.snap
index 6a5e04368e..b804fe58c0 100644
--- a/src/test/unit/__snapshots__/profile-conversion.test.ts.snap
+++ b/src/test/unit/__snapshots__/profile-conversion.test.ts.snap
@@ -591,7 +591,7 @@ Object {
"oscpu": undefined,
"physicalCPUs": undefined,
"platform": undefined,
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "ART Trace (Android)",
"sampleUnits": undefined,
@@ -79192,7 +79192,7 @@ Object {
"oscpu": undefined,
"physicalCPUs": undefined,
"platform": undefined,
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "ART Trace (Android)",
"sampleUnits": undefined,
@@ -315562,7 +315562,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Chrome Trace",
"profilingEndTime": 119159778.026,
@@ -350479,7 +350479,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Chrome Trace",
"profilingEndTime": 119159778.026,
@@ -385375,7 +385375,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Chrome Trace",
"profilingEndTime": 66155012.423,
@@ -387980,7 +387980,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Chrome Trace",
"sourceURL": "",
@@ -389809,7 +389809,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Chrome Trace",
"profilingEndTime": 355035987.653,
@@ -393482,7 +393482,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Chrome Trace",
"sourceURL": "",
@@ -398697,7 +398697,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Chrome Trace",
"profilingEndTime": 66155012.423,
@@ -399739,7 +399739,7 @@ Object {
"oscpu": undefined,
"physicalCPUs": undefined,
"platform": undefined,
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Firefox",
"sampleUnits": undefined,
@@ -403614,7 +403614,7 @@ Object {
"oscpu": undefined,
"physicalCPUs": undefined,
"platform": undefined,
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Firefox",
"sampleUnits": undefined,
@@ -418512,7 +418512,7 @@ Object {
"oscpu": undefined,
"physicalCPUs": undefined,
"platform": undefined,
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Firefox",
"sampleUnits": undefined,
@@ -424719,7 +424719,7 @@ Object {
"oscpu": undefined,
"physicalCPUs": undefined,
"platform": undefined,
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Firefox",
"sampleUnits": undefined,
@@ -441164,7 +441164,7 @@ Object {
"keepProfileThreadOrder": true,
"markerSchema": Array [],
"platform": "Android",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "com.example.sampleapplication",
"sourceCodeIsNotOnSearchfox": true,
@@ -498819,7 +498819,7 @@ Object {
"keepProfileThreadOrder": true,
"markerSchema": Array [],
"platform": "Android",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "com.example.sampleapplication",
"sourceCodeIsNotOnSearchfox": true,
@@ -561079,7 +561079,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "target/debug/examples/work_log (dhat)",
"sourceURL": "",
@@ -563127,7 +563127,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Flamegraph",
"sourceURL": "",
@@ -871013,7 +871013,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Flamegraph",
"sourceURL": "",
diff --git a/src/test/unit/__snapshots__/profile-fetch.test.ts.snap b/src/test/unit/__snapshots__/profile-fetch.test.ts.snap
new file mode 100644
index 0000000000..1de4f42d93
--- /dev/null
+++ b/src/test/unit/__snapshots__/profile-fetch.test.ts.snap
@@ -0,0 +1,55 @@
+// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
+
+exports[`fetchProfile fails if a bad profile JSON is passed in 1`] = `[Error: The profile’s JSON could not be decoded. The full error information has been printed out to the DevTool’s console.]`;
+
+exports[`fetchProfile fails if a bad profile JSON is passed in 2`] = `
+Array [
+ Array [
+ "The profile’s JSON could not be decoded.",
+ ],
+ Array [
+ "JSON parsing error:",
+ [SyntaxError: Unexpected token 'i', "invalid" is not valid JSON],
+ ],
+ Array [
+ "Fetch response:",
+ Response {},
+ ],
+]
+`;
+
+exports[`fetchProfile fails if a bad profile JSON is passed in, with no content type 1`] = `[Error: The profile’s JSON could not be decoded. The full error information has been printed out to the DevTool’s console.]`;
+
+exports[`fetchProfile fails if a bad profile JSON is passed in, with no content type 2`] = `
+Array [
+ Array [
+ "The profile’s JSON could not be decoded.",
+ ],
+ Array [
+ "JSON parsing error:",
+ [SyntaxError: Unexpected token 'i', "invalid" is not valid JSON],
+ ],
+ Array [
+ "Fetch response:",
+ Response {},
+ ],
+]
+`;
+
+exports[`fetchProfile fails if a bad zip file is passed in 1`] = `[Error: Unable to open the archive file. The full error information has been printed out to the DevTool’s console.]`;
+
+exports[`fetchProfile fails if a bad zip file is passed in 2`] = `
+Array [
+ Array [
+ "Unable to open the archive file.",
+ ],
+ Array [
+ "Error:",
+ [Error: Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html],
+ ],
+ Array [
+ "Fetch response:",
+ Response {},
+ ],
+]
+`;
diff --git a/src/test/unit/__snapshots__/profile-upgrading.test.ts.snap b/src/test/unit/__snapshots__/profile-upgrading.test.ts.snap
index e139904c6d..e85d4f0300 100644
--- a/src/test/unit/__snapshots__/profile-upgrading.test.ts.snap
+++ b/src/test/unit/__snapshots__/profile-upgrading.test.ts.snap
@@ -40,7 +40,7 @@ Object {
"oscpu": undefined,
"physicalCPUs": undefined,
"platform": undefined,
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Firefox",
"sampleUnits": undefined,
@@ -7358,7 +7358,7 @@ Object {
"misc": "rv:48.0",
"oscpu": "Intel Mac OS X 10.11",
"platform": "Macintosh",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Firefox",
"stackwalk": 1,
@@ -8693,7 +8693,7 @@ Object {
"misc": "rv:48.0",
"oscpu": "Intel Mac OS X 10.11",
"platform": "Macintosh",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Firefox",
"stackwalk": 1,
@@ -9693,6 +9693,14 @@ Object {
Object {
"category": "Memory",
"description": "Amount of allocated memory",
+ "display": Object {
+ "color": "orange",
+ "graphType": "line-accumulated",
+ "label": "Memory",
+ "markerSchemaLocation": "timeline-memory",
+ "sortWeight": 20,
+ "unit": "bytes",
+ },
"mainThreadIndex": 0,
"name": "malloc",
"pid": "11111",
@@ -10155,7 +10163,7 @@ Object {
"misc": "rv:48.0",
"oscpu": "Intel Mac OS X 10.11",
"platform": "Macintosh",
- "preprocessedProfileVersion": 61,
+ "preprocessedProfileVersion": 62,
"processType": 0,
"product": "Firefox",
"stackwalk": 1,
diff --git a/src/test/unit/__snapshots__/window-console.test.ts.snap b/src/test/unit/__snapshots__/window-console.test.ts.snap
index b307a72a89..8819fb856f 100644
--- a/src/test/unit/__snapshots__/window-console.test.ts.snap
+++ b/src/test/unit/__snapshots__/window-console.test.ts.snap
@@ -35,7 +35,7 @@ Array [
%cwindow.actions%c - All the actions that can be dispatched to change the state.
%cwindow.experimental%c - The object that holds flags of all the experimental features.
%cwindow.togglePseudoLocalization%c - Enable pseudo localizations by passing \\"accented\\" or \\"bidi\\" to this function, or disable using no parameters.
-%cwindow.toggleTimelineType%c - Toggle timeline graph type by passing \\"cpu-category\\", \\"category\\", or \\"stack\\".
+%cwindow.toggleTimelineType%c - Toggle timeline graph type by passing \\"cpu-category\\" or \\"stack\\".
%cwindow.toggleDarkMode%c - Cycle through theme preferences: system, light, dark.
%cwindow.retrieveRawProfileDataFromBrowser%c - Retrieve the profile attached to the current tab and returns it. Use \\"await\\" to call it, and use saveToDisk to save it.
%cwindow.extractGeckoLogs%c - Retrieve recorded logs in the current range, using the MOZ_LOG format. Use with \\"copy\\" or \\"saveToDisk\\".
diff --git a/src/test/unit/profile-fetch.test.ts b/src/test/unit/profile-fetch.test.ts
new file mode 100644
index 0000000000..f971b291ad
--- /dev/null
+++ b/src/test/unit/profile-fetch.test.ts
@@ -0,0 +1,208 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import JSZip from 'jszip';
+
+import { fetchProfile } from '../../utils/profile-fetch';
+import { serializeProfile } from '../../profile-logic/process-profile';
+import { getProfileFromTextSamples } from '../fixtures/profiles/processed-profile';
+import { extractArrayBuffer } from '../fixtures/utils';
+
+import type { Profile } from 'firefox-profiler/types';
+
+function encode(string: string): Uint8Array {
+ return new TextEncoder().encode(string);
+}
+
+/**
+ * This profile will have a single sample, and a single thread.
+ */
+function _getSimpleProfile(): Profile {
+ return getProfileFromTextSamples('A').profile;
+}
+
+/**
+ * fetchProfile has a decent amount of complexity around different issues with loading
+ * in different support URL formats. It's mainly testing what happens when JSON
+ * and zip file is sent, and what happens when things fail.
+ */
+describe('fetchProfile', function () {
+ /**
+ * This helper function encapsulates various configurations for the type of content
+ * as well and response headers.
+ */
+ async function configureFetch(obj: {
+ url: string;
+ contentType?: string;
+ content: 'generated-zip' | 'generated-json' | Uint8Array;
+ }) {
+ const { url, contentType, content } = obj;
+ const stringProfile = serializeProfile(_getSimpleProfile());
+ const profile = JSON.parse(stringProfile);
+ let arrayBuffer;
+
+ switch (content) {
+ case 'generated-zip': {
+ const zip = new JSZip();
+ zip.file('profile.json', stringProfile);
+ arrayBuffer = await zip.generateAsync({ type: 'uint8array' });
+ break;
+ }
+ case 'generated-json':
+ arrayBuffer = encode(stringProfile);
+ break;
+ default:
+ arrayBuffer = content;
+ break;
+ }
+
+ window.fetchMock.catch(403).get(url, {
+ body: arrayBuffer,
+ headers: {
+ 'content-type': contentType,
+ },
+ });
+
+ const reportError = jest.fn();
+ const args = {
+ url,
+ onTemporaryError: () => {},
+ reportError,
+ };
+
+ // Return fetch's args, based on the inputs.
+ return { profile, args, reportError };
+ }
+
+ it('fetches a normal profile with the correct content-type headers', async function () {
+ const { profile, args } = await configureFetch({
+ url: 'https://example.com/profile.json',
+ contentType: 'application/json',
+ content: 'generated-json',
+ });
+
+ const profileOrZip = await fetchProfile(args);
+ expect(profileOrZip).toEqual({ responseType: 'PROFILE', profile });
+ });
+
+ it('fetches a zipped profile with correct content-type headers', async function () {
+ const { args, reportError } = await configureFetch({
+ url: 'https://example.com/profile.zip',
+ contentType: 'application/zip',
+ content: 'generated-zip',
+ });
+
+ const profileOrZip = await fetchProfile(args);
+ expect(profileOrZip.responseType).toBe('ZIP');
+ expect(reportError.mock.calls.length).toBe(0);
+ });
+
+ it('fetches a zipped profile with incorrect content-type headers, but .zip extension', async function () {
+ const { args, reportError } = await configureFetch({
+ url: 'https://example.com/profile.zip',
+ content: 'generated-zip',
+ });
+
+ const profileOrZip = await fetchProfile(args);
+ expect(profileOrZip.responseType).toBe('ZIP');
+ expect(reportError.mock.calls.length).toBe(0);
+ });
+
+ it('fetches a profile with incorrect content-type headers, but .json extension', async function () {
+ const { profile, args, reportError } = await configureFetch({
+ url: 'https://example.com/profile.json',
+ content: 'generated-json',
+ });
+
+ const profileOrZip = await fetchProfile(args);
+ expect(profileOrZip).toEqual({ responseType: 'PROFILE', profile });
+ expect(reportError.mock.calls.length).toBe(0);
+ });
+
+ it('fetches a profile with incorrect content-type headers, no known extension, and attempts to JSON parse it', async function () {
+ const { profile, args, reportError } = await configureFetch({
+ url: 'https://example.com/profile.file',
+ content: 'generated-json',
+ });
+
+ const profileOrZip = await fetchProfile(args);
+ expect(profileOrZip).toEqual({ responseType: 'PROFILE', profile });
+ expect(reportError.mock.calls.length).toBe(0);
+ });
+
+ it('fails if a bad zip file is passed in', async function () {
+ const { args, reportError } = await configureFetch({
+ url: 'https://example.com/profile.file',
+ contentType: 'application/zip',
+ content: new Uint8Array([0, 1, 2, 3]),
+ });
+
+ let userFacingError;
+ try {
+ await fetchProfile(args);
+ } catch (error) {
+ userFacingError = error;
+ }
+ expect(userFacingError).toMatchSnapshot();
+ expect(reportError.mock.calls.length).toBeGreaterThan(0);
+ expect(reportError.mock.calls).toMatchSnapshot();
+ });
+
+ it('fails if a bad profile JSON is passed in', async function () {
+ const invalidJSON = 'invalid';
+ const { args, reportError } = await configureFetch({
+ url: 'https://example.com/profile.json',
+ contentType: 'application/json',
+ content: encode(invalidJSON),
+ });
+
+ let userFacingError;
+ try {
+ await fetchProfile(args);
+ } catch (error) {
+ userFacingError = error;
+ }
+ expect(userFacingError).toMatchSnapshot();
+ expect(reportError.mock.calls.length).toBeGreaterThan(0);
+ expect(reportError.mock.calls).toMatchSnapshot();
+ });
+
+ it('fails if a bad profile JSON is passed in, with no content type', async function () {
+ const invalidJSON = 'invalid';
+ const { args, reportError } = await configureFetch({
+ url: 'https://example.com/profile.json',
+ content: encode(invalidJSON),
+ });
+
+ let userFacingError;
+ try {
+ await fetchProfile(args);
+ } catch (error) {
+ userFacingError = error;
+ }
+ expect(userFacingError).toMatchSnapshot();
+ expect(reportError.mock.calls.length).toBeGreaterThan(0);
+ expect(reportError.mock.calls).toMatchSnapshot();
+ });
+
+ it('fallback behavior if a completely unknown file is passed in', async function () {
+ const invalidJSON = 'invalid';
+ const profile = encode(invalidJSON);
+ const { args } = await configureFetch({
+ url: 'https://example.com/profile.unknown',
+ content: profile,
+ });
+
+ let userFacingError = null;
+ try {
+ const profileOrZip = await fetchProfile(args);
+ expect(profileOrZip).toEqual({
+ responseType: 'PROFILE',
+ profile: extractArrayBuffer(profile),
+ });
+ } catch (error) {
+ userFacingError = error;
+ }
+ expect(userFacingError).toBeNull();
+ });
+});
diff --git a/src/test/unit/profiler-edit.test.ts b/src/test/unit/profiler-edit.test.ts
new file mode 100644
index 0000000000..82205160fa
--- /dev/null
+++ b/src/test/unit/profiler-edit.test.ts
@@ -0,0 +1,147 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import { makeOptionsFromArgv } from '../../node-tools/profiler-edit';
+
+describe('makeOptionsFromArgv', function () {
+ const commonArgs = ['/path/to/node', '/path/to/profiler-edit.js'];
+
+ it('recognizes -i with a file path', function () {
+ const options = makeOptionsFromArgv([
+ ...commonArgs,
+ '-i',
+ '/path/to/profile.json',
+ '-o',
+ '/path/to/output.json',
+ ]);
+ expect(options.input).toEqual({
+ type: 'FILE',
+ path: '/path/to/profile.json',
+ });
+ expect(options.output).toEqual('/path/to/output.json');
+ expect(options.symbolicateWithServer).toBeUndefined();
+ });
+
+ it('recognizes -i with an http URL', function () {
+ const options = makeOptionsFromArgv([
+ ...commonArgs,
+ '-i',
+ 'http://example.com/profile.json',
+ '-o',
+ '/path/to/output.json',
+ ]);
+ expect(options.input).toEqual({
+ type: 'URL',
+ url: 'http://example.com/profile.json',
+ });
+ });
+
+ it('recognizes -i with an https URL', function () {
+ const options = makeOptionsFromArgv([
+ ...commonArgs,
+ '-i',
+ 'https://example.com/profile.json',
+ '-o',
+ '/path/to/output.json',
+ ]);
+ expect(options.input).toEqual({
+ type: 'URL',
+ url: 'https://example.com/profile.json',
+ });
+ });
+
+ it('recognizes --from-file', function () {
+ const options = makeOptionsFromArgv([
+ ...commonArgs,
+ '--from-file',
+ '/path/to/profile.json',
+ '-o',
+ '/path/to/output.json',
+ ]);
+ expect(options.input).toEqual({
+ type: 'FILE',
+ path: '/path/to/profile.json',
+ });
+ });
+
+ it('recognizes --from-url', function () {
+ const options = makeOptionsFromArgv([
+ ...commonArgs,
+ '--from-url',
+ 'https://example.com/profile.json',
+ '-o',
+ '/path/to/output.json',
+ ]);
+ expect(options.input).toEqual({
+ type: 'URL',
+ url: 'https://example.com/profile.json',
+ });
+ });
+
+ it('recognizes --from-hash', function () {
+ const options = makeOptionsFromArgv([
+ ...commonArgs,
+ '--from-hash',
+ 'abc123',
+ '-o',
+ '/path/to/output.json',
+ ]);
+ expect(options.input).toEqual({ type: 'HASH', hash: 'abc123' });
+ });
+
+ it('recognizes --output as an alias for -o', function () {
+ const options = makeOptionsFromArgv([
+ ...commonArgs,
+ '-i',
+ '/path/to/profile.json',
+ '--output',
+ '/path/to/output.json',
+ ]);
+ expect(options.output).toEqual('/path/to/output.json');
+ });
+
+ it('recognizes optional --symbolicate-with-server', function () {
+ const options = makeOptionsFromArgv([
+ ...commonArgs,
+ '-i',
+ '/path/to/profile.json',
+ '-o',
+ '/path/to/output.json',
+ '--symbolicate-with-server',
+ 'http://localhost:8001/',
+ ]);
+ expect(options.symbolicateWithServer).toEqual('http://localhost:8001/');
+ });
+
+ it('throws when no input is provided', function () {
+ expect(() =>
+ makeOptionsFromArgv([...commonArgs, '-o', '/path/to/output.json'])
+ ).toThrow();
+ });
+
+ it('throws when multiple inputs are provided', function () {
+ expect(() =>
+ makeOptionsFromArgv([
+ ...commonArgs,
+ '-i',
+ '/path/to/profile.json',
+ '--from-hash',
+ 'abc123',
+ '-o',
+ '/path/to/output.json',
+ ])
+ ).toThrow();
+ });
+
+ it('throws when no output is provided', function () {
+ expect(() =>
+ makeOptionsFromArgv([...commonArgs, '-i', '/path/to/profile.json'])
+ ).toThrow();
+ });
+
+ it('throws when -i has no value because next token is a flag', function () {
+ expect(() =>
+ makeOptionsFromArgv([...commonArgs, '-i', '-o', '/path/to/output.json'])
+ ).toThrow();
+ });
+});
diff --git a/src/test/unit/symbolicator-cli.test.ts b/src/test/unit/symbolicator-cli.test.ts
deleted file mode 100644
index 59138c332b..0000000000
--- a/src/test/unit/symbolicator-cli.test.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-import { makeOptionsFromArgv } from '../../symbolicator-cli';
-
-describe('makeOptionsFromArgv', function () {
- const commonArgs = ['/path/to/node', '/path/to/symbolicator-cli.js'];
-
- it('should pass arguments into options object', function () {
- const options = makeOptionsFromArgv([
- ...commonArgs,
- '--input',
- '/path/to/input',
- '--output',
- '/path/to/output',
- '--server',
- 'http://symbol.server/',
- ]);
-
- expect(options.input).toEqual('/path/to/input');
- expect(options.output).toEqual('/path/to/output');
- expect(options.server).toEqual('http://symbol.server/');
- });
-
- it('should throw if an argument is missing', function () {
- expect(() => makeOptionsFromArgv(commonArgs)).toThrow();
-
- expect(() =>
- makeOptionsFromArgv([...commonArgs, '--input', 'value'])
- ).toThrow();
- expect(() =>
- makeOptionsFromArgv([...commonArgs, '--output', 'value'])
- ).toThrow();
- expect(() =>
- makeOptionsFromArgv([...commonArgs, '--server', 'value'])
- ).toThrow();
-
- expect(() =>
- makeOptionsFromArgv([
- ...commonArgs,
- '--output',
- 'value',
- '--server',
- 'value',
- ])
- ).toThrow();
- expect(() =>
- makeOptionsFromArgv([
- ...commonArgs,
- '--input',
- 'value',
- '--server',
- 'value',
- ])
- ).toThrow();
- expect(() =>
- makeOptionsFromArgv([
- ...commonArgs,
- '--input',
- 'value',
- '--output',
- 'value',
- ])
- ).toThrow();
- });
-
- it('should throw if argument has no specified value', function () {
- expect(() =>
- makeOptionsFromArgv([
- ...commonArgs,
- '--input',
- '--output',
- 'value',
- '--server',
- 'value',
- ])
- ).toThrow();
- expect(() =>
- makeOptionsFromArgv([
- ...commonArgs,
- '--input',
- 'value',
- '--output',
- '--server',
- 'value',
- ])
- ).toThrow();
- expect(() =>
- makeOptionsFromArgv([
- ...commonArgs,
- '--input',
- 'value',
- '--output',
- 'value',
- '--server',
- ])
- ).toThrow();
- });
-});
diff --git a/src/test/unit/window-console.test.ts b/src/test/unit/window-console.test.ts
index 82c939f7c3..8dbd8a0a3f 100644
--- a/src/test/unit/window-console.test.ts
+++ b/src/test/unit/window-console.test.ts
@@ -112,6 +112,56 @@ describe('console-accessible values on the window object', function () {
`);
});
+ it('can extract gecko logs in new structured format', function () {
+ const profile = getProfileWithMarkers([
+ [
+ 'nsHttp',
+ 170,
+ null,
+ {
+ type: 'Log',
+ level: 1,
+ message:
+ 'ParentChannelListener::ParentChannelListener [this=7fb5e19b98d0]',
+ },
+ ],
+ [
+ 'nsJarProtocol',
+ 190,
+ null,
+ {
+ type: 'Log',
+ level: 2,
+ message: 'nsJARChannel::nsJARChannel [this=0x87f1ec80]\n',
+ },
+ ],
+ ['cubeb', 200, null, { type: 'Log', level: 3, message: 'cubeb_init' }],
+ [
+ 'AudioStream',
+ 210,
+ null,
+ { type: 'Log', level: 4, message: 'AudioStream init\n' },
+ ],
+ [
+ 'VideoSink',
+ 220,
+ null,
+ { type: 'Log', level: 5, message: 'VideoSink::VideoSink' },
+ ],
+ ]);
+ const store = storeWithProfile(profile);
+ const target: MixedObject = {};
+ addDataToWindowObject(store.getState, store.dispatch, target);
+ const result = (target as any).extractGeckoLogs();
+ expect(result).toBe(stripIndent`
+ 1970-01-01 00:00:00.170000000 UTC - [Unknown Process 0: Empty]: E/nsHttp ParentChannelListener::ParentChannelListener [this=7fb5e19b98d0]
+ 1970-01-01 00:00:00.190000000 UTC - [Unknown Process 0: Empty]: W/nsJarProtocol nsJARChannel::nsJARChannel [this=0x87f1ec80]
+ 1970-01-01 00:00:00.200000000 UTC - [Unknown Process 0: Empty]: I/cubeb cubeb_init
+ 1970-01-01 00:00:00.210000000 UTC - [Unknown Process 0: Empty]: D/AudioStream AudioStream init
+ 1970-01-01 00:00:00.220000000 UTC - [Unknown Process 0: Empty]: V/VideoSink VideoSink::VideoSink
+ `);
+ });
+
describe('totalMarkerDuration', function () {
function setup(): ExtraPropertiesOnWindowForConsole {
jest.spyOn(console, 'log').mockImplementation(() => {});
diff --git a/src/test/url-handling.test.ts b/src/test/url-handling.test.ts
index ad61c235cb..30abd56b90 100644
--- a/src/test/url-handling.test.ts
+++ b/src/test/url-handling.test.ts
@@ -20,6 +20,7 @@ import {
closeBottomBox,
changeShowUserTimings,
changeStackChartSameWidths,
+ changeIncludeIdleSamples,
changeSelectedMarker,
} from '../actions/profile-view';
import { changeSelectedTab, changeProfilesToCompare } from '../actions/app';
@@ -51,6 +52,7 @@ import {
import {
getProfileFromTextSamples,
getProfileWithMarkers,
+ getCounterForThread,
} from './fixtures/profiles/processed-profile';
import { selectedThreadSelectors } from '../selectors/per-thread';
import {
@@ -1234,14 +1236,19 @@ describe('url upgrading', function () {
expect(query.timelineType).toBeFalsy();
});
- it('add an explicit category from the url', function () {
+ it('maps the implicit category type to cpu-category', function () {
+ // In v6, the default timeline type was 'category'. The v7 upgrader adds
+ // an explicit 'category' to the URL, which is then parsed as 'cpu-category'
+ // since the two are now equivalent.
const { getState } = _getStoreWithURL({
pathname: '/public/e71ce9584da34298627fb66ac7f2f245ba5edbf5/calltree/',
search: '',
v: 6,
});
- expect(urlStateSelectors.getTimelineType(getState())).toBe('category');
+ expect(urlStateSelectors.getTimelineType(getState())).toBe(
+ 'cpu-category'
+ );
const newUrl = new URL(
urlFromState(urlStateSelectors.getUrlState(getState())),
@@ -1250,7 +1257,7 @@ describe('url upgrading', function () {
const query = queryString.parse(newUrl.search.substr(1), {
arrayFormat: 'bracket',
});
- expect(query.timelineType).toBe('category');
+ expect(query.timelineType).toBeFalsy();
});
it('keeps stack category the same', function () {
@@ -1273,6 +1280,142 @@ describe('url upgrading', function () {
});
});
+ describe('version 16: collapse counter track types into a single counter type', function () {
+ // Build a profile whose pid '222' has one main thread with an IPC marker and
+ // three counters (Memory, power, Bandwidth). This exercises the v16 upgrader:
+ // under the pre-v16 LOCAL_TRACK_INDEX_ORDER the ipc track sat between
+ // 'memory' (slot 2) and 'power' (slot 6), which no longer holds now that all
+ // counters share slot 2.
+ function buildCounterProfile() {
+ const { profile } = getProfileFromTextSamples('A B C D E');
+ const mainThread = profile.threads[0];
+ mainThread.pid = '222';
+ mainThread.name = 'GeckoMain';
+ mainThread.isMainThread = true;
+ mainThread.processType = 'tab';
+
+ // Push a single IPC marker onto the main thread. The upgrader only
+ // checks markers.data[i].type === 'IPC', so a minimal payload is enough.
+ const stringTable = StringTable.withBackingArray(
+ profile.shared.stringArray
+ );
+ mainThread.markers.name.push(stringTable.indexForString('IPC'));
+ mainThread.markers.phase.push(0);
+ mainThread.markers.startTime.push(0);
+ mainThread.markers.endTime.push(null);
+ mainThread.markers.category.push(0);
+ mainThread.markers.data.push({
+ type: 'IPC',
+ startTime: 0,
+ endTime: 1,
+ otherPid: '333',
+ messageSeqno: 1,
+ messageType: 'Foo',
+ side: 'parent',
+ direction: 'sending',
+ phase: 'endpoint',
+ sync: false,
+ } as any);
+ mainThread.markers.length++;
+
+ const memoryCounter = getCounterForThread(mainThread, 0);
+ memoryCounter.category = 'Memory';
+ memoryCounter.name = 'Memory';
+ const powerCounter = getCounterForThread(mainThread, 0);
+ powerCounter.category = 'power';
+ powerCounter.name = 'Power';
+ const bandwidthCounter = getCounterForThread(mainThread, 0);
+ bandwidthCounter.category = 'Bandwidth';
+ bandwidthCounter.name = 'Bandwidth';
+ profile.counters = [memoryCounter, powerCounter, bandwidthCounter];
+
+ return profile;
+ }
+
+ it('remaps localTrackOrderByPid when counter tracks change position', function () {
+ const profile = buildCounterProfile();
+
+ // Pre-v16 layout for pid '222' (sorted by old LOCAL_TRACK_INDEX_ORDER):
+ // [0] memory (slot 2)
+ // [1] ipc (slot 3)
+ // [2] power (slot 6)
+ // [3] bandwidth (slot 8)
+ const oldOrder = [3, 2, 1, 0];
+
+ // Post-v16 layout: counters grouped at slot 2, ipc at slot 3.
+ // [0] memory (counter, insertion order)
+ // [1] power (counter)
+ // [2] bandwidth (counter)
+ // [3] ipc
+ const expectedNewOrder = [2, 1, 3, 0];
+
+ const { query } = upgradeLocationToCurrentVersion(
+ {
+ pathname: '',
+ hash: '',
+ query: {
+ v: '15',
+ localTrackOrderByPid:
+ '222-' + encodeUintArrayForUrlComponent(oldOrder),
+ },
+ },
+ profile
+ );
+
+ expect(query.localTrackOrderByPid).toBe(
+ '222-' + encodeUintArrayForUrlComponent(expectedNewOrder)
+ );
+ });
+
+ it('remaps hiddenLocalTracksByPid when counter tracks change position', function () {
+ const profile = buildCounterProfile();
+
+ // Hide the old 'ipc' (index 1) and old 'bandwidth' (index 3).
+ const oldHidden = new Set([1, 3]);
+ // In the new layout those tracks live at indexes 3 (ipc) and 2 (bandwidth).
+ const expectedNewHidden = new Set([3, 2]);
+
+ const { query } = upgradeLocationToCurrentVersion(
+ {
+ pathname: '',
+ hash: '',
+ query: {
+ v: '15',
+ hiddenLocalTracksByPid:
+ '222-' + encodeUintSetForUrlComponent(oldHidden),
+ },
+ },
+ profile
+ );
+
+ expect(query.hiddenLocalTracksByPid).toBe(
+ '222-' + encodeUintSetForUrlComponent(expectedNewHidden)
+ );
+ });
+
+ it('leaves unrelated PIDs untouched', function () {
+ const profile = buildCounterProfile();
+
+ // pid '999' isn't in the profile, so the upgrader has nothing to remap
+ // for it and should leave the segment as-is.
+ const untouched = '999-' + encodeUintArrayForUrlComponent([1, 0]);
+
+ const { query } = upgradeLocationToCurrentVersion(
+ {
+ pathname: '',
+ hash: '',
+ query: {
+ v: '15',
+ localTrackOrderByPid: untouched,
+ },
+ },
+ profile
+ );
+
+ expect(query.localTrackOrderByPid).toBe(untouched);
+ });
+ });
+
// More general checks
it("won't run if the current version is specified", function () {
const { getState } = _getStoreWithURL({
@@ -1659,6 +1802,28 @@ describe('stack chart specific queries', function () {
});
});
+describe('"include idle samples" query', function () {
+ it('defaults to true and is absent from the URL', function () {
+ const { getState } = _getStoreWithURL();
+ expect(urlStateSelectors.getIncludeIdleSamples(getState())).toBe(true);
+ expect(getQueryStringFromState(getState())).not.toContain(
+ 'hideIdleSamples'
+ );
+ });
+
+ it('persists hideIdleSamples through a URL roundtrip when toggled off', function () {
+ const { getState, dispatch } = _getStoreWithURL();
+
+ dispatch(changeIncludeIdleSamples(false));
+ expect(getQueryStringFromState(getState())).toContain('hideIdleSamples');
+
+ const storeAfterReload = _getStoreFromStateAfterUrlRoundtrip(getState());
+ expect(
+ urlStateSelectors.getIncludeIdleSamples(storeAfterReload.getState())
+ ).toBe(false);
+ });
+});
+
describe('symbolServerUrl', function () {
function setup(search: string) {
jest.spyOn(console, 'error').mockImplementation(() => {});
diff --git a/src/types/actions.ts b/src/types/actions.ts
index b3dccd0f99..8bd6eadb26 100644
--- a/src/types/actions.ts
+++ b/src/types/actions.ts
@@ -85,7 +85,10 @@ export type DataSource =
// this browser, and allows deleting / unpublishing those profiles.
| 'uploaded-recordings';
-export type TimelineType = 'stack' | 'category' | 'cpu-category';
+// Controls which graph is shown in thread tracks.
+// 'cpu-category': Shows the category activity graph.
+// 'stack': Shows the stack graph, for profiles without category information.
+export type TimelineType = 'stack' | 'cpu-category';
export type PreviewSelection = {
readonly isModifying: boolean;
readonly selectionStart: number;
@@ -318,9 +321,6 @@ type ProfileAction =
readonly type: 'SET_CONTEXT_MENU_VISIBILITY';
readonly isVisible: boolean;
}
- | {
- readonly type: 'INCREMENT_PANEL_LAYOUT_GENERATION';
- }
| { readonly type: 'HAS_ZOOMED_VIA_MOUSEWHEEL' }
| { readonly type: 'DISMISS_NEWLY_PUBLISHED' }
| {
@@ -363,6 +363,9 @@ type ProfileAction =
| {
readonly type: 'CLOSE_BOTTOM_BOX_FOR_TAB';
readonly tab: TabSlug;
+ }
+ | {
+ readonly type: 'TOGGLE_BOTTOM_BOX_FULLSCREEN';
};
type ReceiveProfileAction =
@@ -523,6 +526,10 @@ type UrlStateAction =
readonly type: 'CHANGE_SHOW_USER_TIMINGS';
readonly showUserTimings: boolean;
}
+ | {
+ readonly type: 'CHANGE_INCLUDE_IDLE_SAMPLES';
+ readonly includeIdleSamples: boolean;
+ }
| {
readonly type: 'CHANGE_STACK_CHART_SAME_WIDTHS';
readonly stackChartSameWidths: boolean;
diff --git a/src/types/markers.ts b/src/types/markers.ts
index 7c2d63d4a8..9f15b29104 100644
--- a/src/types/markers.ts
+++ b/src/types/markers.ts
@@ -634,11 +634,17 @@ export type ChromeEventPayload = {
* Gecko includes rich log information. This marker payload is used to mirror that
* log information in the profile.
*/
-export type LogMarkerPayload = {
- type: 'Log';
- name: string;
- module: string;
-};
+export type LogMarkerPayload =
+ | {
+ type: 'Log';
+ name: string;
+ module: string;
+ }
+ | {
+ type: 'Log';
+ level: number;
+ message: string;
+ };
export type DOMEventMarkerPayload = {
type: 'DOMEvent';
@@ -711,7 +717,6 @@ export type BHRMarkerPayload = {
export type LongTaskMarkerPayload = {
type: 'MainThreadLongTask';
- category: 'LongTask';
};
export type JsAllocationPayload_Gecko = {
diff --git a/src/types/profile-derived.ts b/src/types/profile-derived.ts
index f52454fd9e..cc641fbe78 100644
--- a/src/types/profile-derived.ts
+++ b/src/types/profile-derived.ts
@@ -13,7 +13,6 @@ import type {
IndexIntoResourceTable,
IndexIntoLibs,
CounterIndex,
- GraphColor,
IndexIntoRawMarkerTable,
IndexIntoStringTable,
TabID,
@@ -33,6 +32,7 @@ import type {
IndexIntoFrameTable,
SourceTable,
IndexIntoSourceTable,
+ CounterDisplayConfig,
} from './profile';
import type { IndexedArray } from './utils';
import type { BitSet } from '../utils/bitset';
@@ -187,10 +187,10 @@ export type Counter = {
name: string;
category: string;
description: string;
- color?: GraphColor;
pid: Pid;
mainThreadIndex: ThreadIndex;
samples: CounterSamplesTable;
+ display: CounterDisplayConfig;
};
/**
@@ -634,12 +634,9 @@ export type GlobalTrack =
export type LocalTrack =
| { readonly type: 'thread'; readonly threadIndex: ThreadIndex }
| { readonly type: 'network'; readonly threadIndex: ThreadIndex }
- | { readonly type: 'memory'; readonly counterIndex: CounterIndex }
- | { readonly type: 'bandwidth'; readonly counterIndex: CounterIndex }
+ | { readonly type: 'counter'; readonly counterIndex: CounterIndex }
| { readonly type: 'ipc'; readonly threadIndex: ThreadIndex }
| { readonly type: 'event-delay'; readonly threadIndex: ThreadIndex }
- | { readonly type: 'process-cpu'; readonly counterIndex: CounterIndex }
- | { readonly type: 'power'; readonly counterIndex: CounterIndex }
| {
readonly type: 'marker';
readonly threadIndex: ThreadIndex;
diff --git a/src/types/profile.ts b/src/types/profile.ts
index 90486b7ecd..04d8a2ee79 100644
--- a/src/types/profile.ts
+++ b/src/types/profile.ts
@@ -3,7 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import type { Milliseconds, Address, Microseconds, Bytes } from './units';
-import type { MarkerPayload, MarkerSchema, MarkerFormatType } from './markers';
+import type {
+ MarkerPayload,
+ MarkerSchema,
+ MarkerFormatType,
+ MarkerDisplayLocation,
+} from './markers';
import type { MarkerPhase, ProfilingLog } from './gecko-profile';
export type IndexIntoStackTable = number;
@@ -529,14 +534,35 @@ export type GraphColor =
| 'teal'
| 'yellow';
+export type CounterGraphType = 'line-accumulated' | 'line-rate';
+
+/**
+ * Specifies how a counter should be displayed in the UI.
+ */
+export type CounterDisplayConfig = {
+ graphType: CounterGraphType;
+ unit: string;
+ color: GraphColor;
+ // The marker schema display location to filter markers for this track,
+ // e.g., "timeline-memory". If null, no markers are shown.
+ markerSchemaLocation: MarkerDisplayLocation | null;
+ // Controls the default display position of this counter track relative to
+ // other tracks. Tracks with lower values appear closer to the top.
+ sortWeight: number;
+ // The human-readable label shown in the track sidebar. For known counter
+ // types this is a friendly name (eg, "Memory"); for generic counters
+ // it falls back to counter.name.
+ label: string;
+};
+
export type RawCounter = {
name: string;
category: string;
description: string;
- color?: GraphColor;
pid: Pid;
mainThreadIndex: ThreadIndex;
samples: RawCounterSamplesTable;
+ display: CounterDisplayConfig;
};
/**
diff --git a/src/types/state.ts b/src/types/state.ts
index 6e18bb2630..7e47f287ae 100644
--- a/src/types/state.ts
+++ b/src/types/state.ts
@@ -186,7 +186,6 @@ export type AppState = {
readonly hasZoomedViaMousewheel: boolean;
readonly isSidebarOpenPerPanel: IsOpenPerPanelState;
readonly sidebarOpenCategories: Map>;
- readonly panelLayoutGeneration: number;
readonly lastVisibleThreadTabSlug: TabSlug;
readonly trackThreadHeights: Record;
readonly isNewlyPublished: boolean;
@@ -356,6 +355,7 @@ export type ProfileSpecificUrlState = {
implementation: ImplementationFilter;
lastSelectedCallTreeSummaryStrategy: CallTreeSummaryStrategy;
invertCallstack: boolean;
+ includeIdleSamples: boolean;
showUserTimings: boolean;
stackChartSameWidths: boolean;
committedRanges: StartEndRange[];
@@ -367,6 +367,7 @@ export type ProfileSpecificUrlState = {
sourceView: SourceViewState;
assemblyView: AssemblyViewState;
isBottomBoxOpenPerPanel: IsOpenPerPanelState;
+ isBottomBoxFullscreen: boolean;
globalTrackOrder: TrackIndex[];
hiddenGlobalTracks: Set;
hiddenLocalTracksByPid: Map>;
diff --git a/src/utils/bitset.ts b/src/utils/bitset.ts
index 2393189679..5dcd1db063 100644
--- a/src/utils/bitset.ts
+++ b/src/utils/bitset.ts
@@ -54,6 +54,15 @@ export function combineTwoBitSetsWithAnd(a: BitSet, b: BitSet): BitSet {
return result;
}
+export function combineTwoBitSetsWithOr(a: BitSet, b: BitSet): BitSet {
+ const slotCount = a.length;
+ const result = new Int32Array(slotCount);
+ for (let i = 0; i < slotCount; i++) {
+ result[i] = a[i] | b[i];
+ }
+ return result;
+}
+
export class BitSetOutOfBoundsError extends Error {
override name = 'BitSetOutOfBoundsError';
bitIndex: number;
diff --git a/src/utils/colors.ts b/src/utils/colors.ts
index 0efd24d0f6..b93ec771d3 100644
--- a/src/utils/colors.ts
+++ b/src/utils/colors.ts
@@ -10,12 +10,14 @@ import {
GREEN_50,
GREEN_60,
GREEN_70,
+ GREY_10,
GREY_20,
GREY_30,
GREY_40,
GREY_50,
GREY_60,
GREY_70,
+ GREY_80,
MAGENTA_60,
MAGENTA_70,
ORANGE_50,
@@ -209,6 +211,23 @@ export function mapCategoryColorNameToStackChartStyles(
return mapCategoryColorNameToStyles(colorName);
}
+/**
+ * A neutral style used to dim non-matching nodes in the stack chart when a
+ * search filter is active. Closer to the background than any category color
+ * so that matching nodes stand out clearly.
+ */
+const DIMMED_STYLE: ColorStyles = {
+ ...DEFAULT_STYLE,
+ _selectedFillStyle: [GREY_10, GREY_80],
+ _unselectedFillStyle: [GREY_10, GREY_80],
+ _selectedTextColor: [GREY_50, GREY_40],
+ gravity: 0,
+};
+
+export function getDimmedStyles(): ColorStyles {
+ return DIMMED_STYLE;
+}
+
export function getForegroundColor(): string {
return lightDark('#000000', GREY_20);
}
diff --git a/src/utils/profile-fetch.ts b/src/utils/profile-fetch.ts
new file mode 100644
index 0000000000..3a7f1638ba
--- /dev/null
+++ b/src/utils/profile-fetch.ts
@@ -0,0 +1,346 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import { oneLine } from 'common-tags';
+import { assertExhaustiveCheck } from './types';
+import { TemporaryError } from './errors';
+import { decompress, isGzip } from './gz';
+import { isLocalURL } from './url';
+import { GOOGLE_STORAGE_BUCKET } from 'firefox-profiler/app-logic/constants';
+import type JSZip from 'jszip';
+
+/**
+ * Shared utilities for fetching profiles from URLs.
+ * Used by both the web app (receive-profile.ts) and the CLI (profile-query).
+ *
+ * This module was extracted from receive-profile.ts to make the fetching
+ * logic reusable across different contexts (Redux vs CLI).
+ */
+
+/**
+ * Convert a profile hash to its Google Cloud Storage URL.
+ * Public profiles are stored in Google Cloud Storage in the profile-store bucket.
+ * See https://cloud.google.com/storage/docs/access-public-data
+ */
+export function getProfileUrlForHash(hash: string): string {
+ return `https://storage.googleapis.com/${GOOGLE_STORAGE_BUCKET}/${hash}`;
+}
+
+/**
+ * Extract the actual profile URL from a profiler.firefox.com URL.
+ *
+ * Parses URLs like:
+ * - https://profiler.firefox.com/from-url/http%3A%2F%2F127.0.0.1%3A3000%2Fprofile.json/
+ * - https://profiler.firefox.com/public/g9w0fmjjx4bqrky4zg0wb90n65b8g3w0qjjx1t0/calltree/
+ *
+ * Returns the decoded profile URL, or null if this is not a supported datasource.
+ * This mimics the logic in retrieveProfileFromStore and retrieveProfileForRawUrl
+ * from receive-profile.ts
+ */
+export function extractProfileUrlFromProfilerUrl(
+ profilerUrl: string
+): string | null {
+ try {
+ // Handle both full URLs and just pathnames
+ let pathname: string;
+ if (
+ profilerUrl.startsWith('http://') ||
+ profilerUrl.startsWith('https://')
+ ) {
+ const url = new URL(profilerUrl);
+ pathname = url.pathname;
+ } else {
+ pathname = profilerUrl;
+ }
+
+ const pathParts = pathname.split('/').filter((d) => d);
+
+ // Check if this is a from-url datasource
+ // URL structure: /from-url/{encoded-profile-url}/...
+ if (pathParts[0] === 'from-url' && pathParts[1]) {
+ return decodeURIComponent(pathParts[1]);
+ }
+
+ // Check if this is a public datasource
+ // URL structure: /public/{hash}/...
+ // Profile is stored in Google Cloud Storage
+ if (pathParts[0] === 'public' && pathParts[1]) {
+ const hash = pathParts[1];
+ return getProfileUrlForHash(hash);
+ }
+
+ return null;
+ } catch (error) {
+ console.error('Failed to parse profiler URL:', error);
+ return null;
+ }
+}
+
+function _wait(delayMs: number): Promise {
+ return new Promise((resolve) => setTimeout(resolve, delayMs));
+}
+
+/**
+ * Check if a load failure is likely due to Safari's localhost HTTP restriction.
+ * Safari blocks mixed content (HTTP on HTTPS page) even for localhost.
+ * This check works in both browser and Node.js (returns false in Node).
+ */
+function _loadProbablyFailedDueToSafariLocalhostHTTPRestriction(
+ url: string,
+ error: Error
+): boolean {
+ // In Node.js, navigator won't exist
+ if (
+ typeof navigator === 'undefined' ||
+ !navigator.userAgent.match(/Safari\/\d+\.\d+/)
+ ) {
+ return false;
+ }
+ // Check if Safari considers this mixed content.
+ try {
+ const parsedUrl = new URL(url);
+ return (
+ error.name === 'TypeError' &&
+ parsedUrl.protocol === 'http:' &&
+ isLocalURL(parsedUrl) &&
+ typeof location !== 'undefined' &&
+ location.protocol === 'https:'
+ );
+ } catch {
+ return false;
+ }
+}
+
+export class SafariLocalhostHTTPLoadError extends Error {
+ override name = 'SafariLocalhostHTTPLoadError';
+}
+
+/**
+ * Deduce the file type from a URL and content type.
+ * This is used to detect zip files vs profile files.
+ * Exported for use in receive-profile.ts for file handling.
+ */
+export function deduceContentType(
+ url: string,
+ contentType: string | null
+): 'application/json' | 'application/zip' | null {
+ if (contentType === 'application/zip' || contentType === 'application/json') {
+ return contentType;
+ }
+ if (url.match(/\.zip$/)) {
+ return 'application/zip';
+ }
+ if (url.match(/\.json/)) {
+ return 'application/json';
+ }
+ return null;
+}
+
+/**
+ * Parse JSON from an optionally gzipped array buffer.
+ * Exported for use in receive-profile.ts for direct file processing.
+ */
+export async function extractJsonFromArrayBuffer(
+ arrayBuffer: ArrayBuffer
+): Promise {
+ let profileBytes = new Uint8Array(arrayBuffer);
+ // Check for the gzip magic number in the header.
+ if (isGzip(profileBytes)) {
+ profileBytes = await decompress(profileBytes);
+ }
+
+ const textDecoder = new TextDecoder();
+ return JSON.parse(textDecoder.decode(profileBytes));
+}
+
+/**
+ * Don't trust third party responses, try and handle a variety of responses gracefully.
+ */
+async function _extractJsonFromResponse(
+ response: Response,
+ reportError: (...data: Array) => void,
+ fileType: 'application/json' | null
+): Promise {
+ let arrayBuffer: ArrayBuffer | null = null;
+ try {
+ // await before returning so that we can catch JSON parse errors.
+ arrayBuffer = await response.arrayBuffer();
+ return await extractJsonFromArrayBuffer(arrayBuffer);
+ } catch (error) {
+ // Change the error message depending on the circumstance:
+ let message;
+ if (error && typeof error === 'object' && error.name === 'AbortError') {
+ message = 'The network request to load the profile was aborted.';
+ } else if (fileType === 'application/json') {
+ message = 'The profile’s JSON could not be decoded.';
+ } else if (fileType === null && arrayBuffer !== null) {
+ // If the content type is not specified, use a raw array buffer
+ // to fallback to other supported profile formats.
+ return arrayBuffer;
+ } else {
+ message = oneLine`
+ The profile could not be downloaded and decoded. This does not look like a supported file
+ type.
+ `;
+ }
+
+ // Provide helpful debugging information to the console.
+ reportError(message);
+ reportError('JSON parsing error:', error);
+ reportError('Fetch response:', response);
+
+ throw new Error(
+ `${message} The full error information has been printed out to the DevTool’s console.`
+ );
+ }
+}
+
+/**
+ * Attempt to load a zip file from a third party. This process can fail, so make sure
+ * to handle and report the error if it does.
+ */
+async function _extractZipFromResponse(
+ response: Response,
+ reportError: (...data: Array) => void
+): Promise {
+ const buffer = await response.arrayBuffer();
+ // Workaround for https://github.com/Stuk/jszip/issues/941
+ // When running this code in tests, `buffer` doesn't inherits from _this_
+ // realm's ArrayBuffer object, and this breaks JSZip which doesn't account for
+ // this case. We workaround the issue by wrapping the buffer in an Uint8Array
+ // that comes from this realm.
+ const typedBuffer = new Uint8Array(buffer);
+ try {
+ const { default: JSZip } = await import('jszip');
+ const zip = await JSZip.loadAsync(typedBuffer);
+ // Catch the error if unable to load the zip.
+ return zip;
+ } catch (error) {
+ const message = 'Unable to open the archive file.';
+ reportError(message);
+ reportError('Error:', error);
+ reportError('Fetch response:', response);
+ throw new Error(
+ `${message} The full error information has been printed out to the DevTool’s console.`
+ );
+ }
+}
+
+export type ProfileOrZip =
+ | { responseType: 'PROFILE'; profile: unknown }
+ | { responseType: 'ZIP'; zip: JSZip };
+
+/**
+ * This function guesses the correct content-type (even if one isn't sent) and then
+ * attempts to use the proper method to extract the response.
+ */
+async function _extractProfileOrZipFromResponse(
+ url: string,
+ response: Response,
+ reportError: (...data: Array) => void
+): Promise {
+ const contentType = deduceContentType(
+ url,
+ response.headers.get('content-type')
+ );
+ switch (contentType) {
+ case 'application/zip':
+ return {
+ responseType: 'ZIP',
+ zip: await _extractZipFromResponse(response, reportError),
+ };
+ case 'application/json':
+ case null:
+ // The content type is null if it is unknown, or an unsupported type. Go ahead
+ // and try to process it as a profile.
+ return {
+ responseType: 'PROFILE',
+ profile: await _extractJsonFromResponse(
+ response,
+ reportError,
+ contentType
+ ),
+ };
+ default:
+ throw assertExhaustiveCheck(contentType);
+ }
+}
+
+export type FetchProfileArgs = {
+ url: string;
+ onTemporaryError: (param: TemporaryError) => void;
+ // Allow tests to capture the reported error, but normally use console.error.
+ reportError?: (...data: Array) => void;
+};
+
+/**
+ * Tries to fetch a profile on `url`. If the profile is not found,
+ * `onTemporaryError` is called with an appropriate error, we wait 1 second, and
+ * then tries again. If we still can't find the profile after 11 tries, the
+ * returned promise is rejected with a fatal error.
+ * If we can retrieve the profile properly, the returned promise is resolved
+ * with the parsed profile or zip file.
+ *
+ * This function was moved from receive-profile.ts to make it reusable by
+ * both the web app and CLI.
+ */
+export async function fetchProfile(
+ args: FetchProfileArgs
+): Promise {
+ const MAX_WAIT_SECONDS = 10;
+ let i = 0;
+ const { url, onTemporaryError } = args;
+ // Allow tests to capture the reported error, but normally use console.error.
+ const reportError = args.reportError || console.error;
+
+ while (true) {
+ let response;
+ try {
+ response = await fetch(url);
+ } catch (e) {
+ // Case 1: Exception.
+ if (
+ _loadProbablyFailedDueToSafariLocalhostHTTPRestriction(url, e as Error)
+ ) {
+ throw new SafariLocalhostHTTPLoadError();
+ }
+ throw e;
+ }
+
+ // Case 2: successful answer.
+ if (response.ok) {
+ return _extractProfileOrZipFromResponse(url, response, reportError);
+ }
+
+ // case 3: unrecoverable error.
+ if (response.status !== 403) {
+ throw new Error(oneLine`
+ Could not fetch the profile on remote server.
+ Response was: ${response.status} ${response.statusText}.
+ `);
+ }
+
+ // case 4: 403 errors can be transient while a profile is uploaded.
+
+ if (i++ === MAX_WAIT_SECONDS) {
+ // In the last iteration we don't send a temporary error because we'll
+ // throw an error right after the while loop.
+ break;
+ }
+
+ onTemporaryError(
+ new TemporaryError(
+ 'Profile not found on remote server.',
+ { count: i, total: MAX_WAIT_SECONDS + 1 } // 11 tries during 10 seconds
+ )
+ );
+
+ await _wait(1000);
+ }
+
+ throw new Error(oneLine`
+ Could not fetch the profile on remote server:
+ still not found after ${MAX_WAIT_SECONDS} seconds.
+ `);
+}
diff --git a/src/utils/window-console.ts b/src/utils/window-console.ts
index bb48b25674..96bb9c74b3 100644
--- a/src/utils/window-console.ts
+++ b/src/utils/window-console.ts
@@ -9,6 +9,7 @@ import type {
Profile,
Thread,
Marker,
+ LogMarkerPayload,
} from 'firefox-profiler/types';
import { selectorsForConsole } from 'firefox-profiler/selectors';
import actions from 'firefox-profiler/actions';
@@ -180,14 +181,10 @@ export function addDataToWindowObject(
};
target.toggleTimelineType = function (timelineType?: string) {
- if (
- timelineType !== 'cpu-category' &&
- timelineType !== 'category' &&
- timelineType !== 'stack'
- ) {
+ if (timelineType !== 'cpu-category' && timelineType !== 'stack') {
console.log(stripIndent`
❗ The timeline type "${timelineType}" is unknown.
- 💡 Valid types are: "cpu-category", "category", or "stack".
+ 💡 Valid types are: "cpu-category" or "stack".
Please try again 😊
`);
return;
@@ -301,36 +298,45 @@ export function addDataToWindowObject(
const range =
selectorsForConsole.profile.getPreviewSelectionRange(getState());
+ const LOG_LEVEL_LETTER: Record = {
+ 1: 'E',
+ 2: 'W',
+ 3: 'I',
+ 4: 'D',
+ 5: 'V',
+ };
+
for (const thread of profile.threads) {
const { markers } = thread;
+
for (let i = 0; i < markers.length; i++) {
const startTime = markers.startTime[i];
- // Note that Log markers are instant markers, so they only have a start time.
if (
startTime !== null &&
- markers.data[i] &&
markers.data[i]?.type === 'Log' &&
startTime >= range.start &&
startTime <= range.end
) {
- const data = markers.data[i];
- const markerStartTime = markers.startTime[i];
- if (
- data &&
- markerStartTime !== null &&
- (data as any).module &&
- (data as any).name
- ) {
- const strTimestamp = d2s(profile.meta.startTime + markerStartTime);
- const processName = thread.processName ?? 'Unknown Process';
-
- // The log module may contain the log level for profiles captured after bug 1995503.
- // If the log module does not contain /, we fake it to D/module
- const logModule = (data as any).module;
- const prefix = logModule.includes('/') ? '' : 'D/';
- const statement = `${strTimestamp} - [${processName} ${thread.pid}: ${thread.name}]: ${prefix}${logModule} ${(data as any).name.trim()}`;
- logs.push(statement);
+ const data = markers.data[i] as LogMarkerPayload;
+ const strTimestamp = d2s(profile.meta.startTime + startTime);
+ const processName = thread.processName ?? 'Unknown Process';
+
+ let statement;
+ if ('message' in data) {
+ if (!data.message) {
+ continue;
+ }
+ const moduleName = profile.shared.stringArray[markers.name[i]];
+ const levelLetter = LOG_LEVEL_LETTER[data.level] ?? 'D';
+ statement = `${strTimestamp} - [${processName} ${thread.pid}: ${thread.name}]: ${levelLetter}/${moduleName} ${data.message.trim()}`;
+ } else {
+ if (!data.name) {
+ continue;
+ }
+ const prefix = data.module.includes('/') ? '' : 'D/';
+ statement = `${strTimestamp} - [${processName} ${thread.pid}: ${thread.name}]: ${prefix}${data.module} ${data.name.trim()}`;
}
+ logs.push(statement);
}
}
}
@@ -421,7 +427,7 @@ export function logFriendlyPreamble() {
%cwindow.actions%c - All the actions that can be dispatched to change the state.
%cwindow.experimental%c - The object that holds flags of all the experimental features.
%cwindow.togglePseudoLocalization%c - Enable pseudo localizations by passing "accented" or "bidi" to this function, or disable using no parameters.
- %cwindow.toggleTimelineType%c - Toggle timeline graph type by passing "cpu-category", "category", or "stack".
+ %cwindow.toggleTimelineType%c - Toggle timeline graph type by passing "cpu-category" or "stack".
%cwindow.toggleDarkMode%c - Cycle through theme preferences: system, light, dark.
%cwindow.retrieveRawProfileDataFromBrowser%c - Retrieve the profile attached to the current tab and returns it. Use "await" to call it, and use saveToDisk to save it.
%cwindow.extractGeckoLogs%c - Retrieve recorded logs in the current range, using the MOZ_LOG format. Use with "copy" or "saveToDisk".
diff --git a/yarn.lock b/yarn.lock
index bd6dc08b88..40aad56b21 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -903,10 +903,10 @@
"@babel/helper-create-regexp-features-plugin" "^7.28.5"
"@babel/helper-plugin-utils" "^7.28.6"
-"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.29.0":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.29.0.tgz#c55db400c515a303662faaefd2d87e796efa08d0"
- integrity sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==
+"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.29.2":
+ version "7.29.2"
+ resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.29.2.tgz#5a173f22c7d8df362af1c9fe31facd320de4a86c"
+ integrity sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==
dependencies:
"@babel/compat-data" "^7.29.0"
"@babel/helper-compilation-targets" "^7.28.6"
@@ -1011,7 +1011,7 @@
"@babel/plugin-transform-modules-commonjs" "^7.27.1"
"@babel/plugin-transform-typescript" "^7.28.5"
-"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
+"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3":
version "7.26.10"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.10.tgz#a07b4d8fa27af131a633d7b3524db803eb4764c2"
integrity sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==
@@ -1110,10 +1110,10 @@
"@codemirror/language" "^6.0.0"
"@lezer/rust" "^1.0.0"
-"@codemirror/language@^6.0.0", "@codemirror/language@^6.12.2", "@codemirror/language@^6.6.0":
- version "6.12.2"
- resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.12.2.tgz#7db5a46757411cf251e8f450474c05710c27d42c"
- integrity sha512-jEPmz2nGGDxhRTg3lTpzmIyGKxz3Gp3SJES4b0nAuE5SWQoKdT5GoQ69cwMmFd+wvFUhYirtDTr0/DRHpQAyWg==
+"@codemirror/language@^6.0.0", "@codemirror/language@^6.12.3", "@codemirror/language@^6.6.0":
+ version "6.12.3"
+ resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.12.3.tgz#0b220182973a4c19850b29f7dd82aec1bbae3d7e"
+ integrity sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==
dependencies:
"@codemirror/state" "^6.0.0"
"@codemirror/view" "^6.23.0"
@@ -1131,19 +1131,19 @@
"@codemirror/view" "^6.0.0"
crelt "^1.0.5"
-"@codemirror/state@^6.0.0", "@codemirror/state@^6.5.0", "@codemirror/state@^6.5.4":
- version "6.5.4"
- resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.5.4.tgz#f5be4b8c0d2310180d5f15a9f641c21ca69faf19"
- integrity sha512-8y7xqG/hpB53l25CIoit9/ngxdfoG+fx+V3SHBrinnhOtLvKHRyAJJuHzkWrR4YXXLX8eXBsejgAAxHUOdW1yw==
+"@codemirror/state@^6.0.0", "@codemirror/state@^6.6.0":
+ version "6.6.0"
+ resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.6.0.tgz#b88dbdc14aea4ace3c6d67bb77fe28bb84e4394e"
+ integrity sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==
dependencies:
"@marijn/find-cluster-break" "^1.0.0"
-"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0", "@codemirror/view@^6.39.14":
- version "6.39.14"
- resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.39.14.tgz#ebecaee4c76566c3eb61dfe4d6bf386c617de5cf"
- integrity sha512-WJcvgHm/6Q7dvGT0YFv/6PSkoc36QlR0VCESS6x9tGsnF1lWLmmYxOgX3HH6v8fo6AvSLgpcs+H0Olre6MKXlg==
+"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0", "@codemirror/view@^6.41.0":
+ version "6.41.0"
+ resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.41.0.tgz#482cbcb5f8f90131908e5f9c0e2f4681e0684db0"
+ integrity sha512-6H/qadXsVuDY219Yljhohglve8xf4B8xJkVOEWfA5uiYKiTFppjqsvsfR5iPA0RbvRBoOyTZpbLIxe9+0UR8xA==
dependencies:
- "@codemirror/state" "^6.5.0"
+ "@codemirror/state" "^6.6.0"
crelt "^1.0.6"
style-mod "^4.1.0"
w3c-keyname "^2.2.4"
@@ -1181,10 +1181,10 @@
resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz#e1c65dc09378b42f26a111fca7f7075fc2c26164"
integrity sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==
-"@csstools/css-syntax-patches-for-csstree@^1.0.26":
- version "1.0.28"
- resolved "https://registry.yarnpkg.com/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.28.tgz#cd239a16f95c0ed7c6d74315da4e38f2e93bbf19"
- integrity sha512-1NRf1CUBjnr3K7hu8BLxjQrKCxEe8FP/xmPTenAxCRZWVLbmGotkFvG9mfNpjA6k7Bw1bw4BilZq9cu19RA5pg==
+"@csstools/css-syntax-patches-for-csstree@^1.1.1":
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.3.tgz#3204cf40deb97db83e225b0baa9e37d9c3bd344d"
+ integrity sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==
"@csstools/css-tokenizer@^3.0.3":
version "3.0.4"
@@ -1238,135 +1238,135 @@
resolved "https://registry.yarnpkg.com/@epic-web/invariant/-/invariant-1.0.0.tgz#1073e5dee6dd540410784990eb73e4acd25c9813"
integrity sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==
-"@esbuild/aix-ppc64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz#815b39267f9bffd3407ea6c376ac32946e24f8d2"
- integrity sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==
-
-"@esbuild/android-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz#19b882408829ad8e12b10aff2840711b2da361e8"
- integrity sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==
-
-"@esbuild/android-arm@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.3.tgz#90be58de27915efa27b767fcbdb37a4470627d7b"
- integrity sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==
-
-"@esbuild/android-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.3.tgz#d7dcc976f16e01a9aaa2f9b938fbec7389f895ac"
- integrity sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==
-
-"@esbuild/darwin-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz#9f6cac72b3a8532298a6a4493ed639a8988e8abd"
- integrity sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==
-
-"@esbuild/darwin-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz#ac61d645faa37fd650340f1866b0812e1fb14d6a"
- integrity sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==
-
-"@esbuild/freebsd-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz#b8625689d73cf1830fe58c39051acdc12474ea1b"
- integrity sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==
-
-"@esbuild/freebsd-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz#07be7dd3c9d42fe0eccd2ab9f9ded780bc53bead"
- integrity sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==
-
-"@esbuild/linux-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz#bf31918fe5c798586460d2b3d6c46ed2c01ca0b6"
- integrity sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==
-
-"@esbuild/linux-arm@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz#28493ee46abec1dc3f500223cd9f8d2df08f9d11"
- integrity sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==
-
-"@esbuild/linux-ia32@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz#750752a8b30b43647402561eea764d0a41d0ee29"
- integrity sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==
-
-"@esbuild/linux-loong64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz#a5a92813a04e71198c50f05adfaf18fc1e95b9ed"
- integrity sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==
-
-"@esbuild/linux-mips64el@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz#deb45d7fd2d2161eadf1fbc593637ed766d50bb1"
- integrity sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==
-
-"@esbuild/linux-ppc64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz#6f39ae0b8c4d3d2d61a65b26df79f6e12a1c3d78"
- integrity sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==
-
-"@esbuild/linux-riscv64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz#4c5c19c3916612ec8e3915187030b9df0b955c1d"
- integrity sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==
-
-"@esbuild/linux-s390x@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz#9ed17b3198fa08ad5ccaa9e74f6c0aff7ad0156d"
- integrity sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==
-
-"@esbuild/linux-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz#12383dcbf71b7cf6513e58b4b08d95a710bf52a5"
- integrity sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==
-
-"@esbuild/netbsd-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz#dd0cb2fa543205fcd931df44f4786bfcce6df7d7"
- integrity sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==
-
-"@esbuild/netbsd-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz#028ad1807a8e03e155153b2d025b506c3787354b"
- integrity sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==
-
-"@esbuild/openbsd-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz#e3c16ff3490c9b59b969fffca87f350ffc0e2af5"
- integrity sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==
-
-"@esbuild/openbsd-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz#c5a4693fcb03d1cbecbf8b422422468dfc0d2a8b"
- integrity sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==
-
-"@esbuild/openharmony-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz#082082444f12db564a0775a41e1991c0e125055e"
- integrity sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==
-
-"@esbuild/sunos-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz#5ab036c53f929e8405c4e96e865a424160a1b537"
- integrity sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==
-
-"@esbuild/win32-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz#38de700ef4b960a0045370c171794526e589862e"
- integrity sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==
-
-"@esbuild/win32-ia32@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz#451b93dc03ec5d4f38619e6cd64d9f9eff06f55c"
- integrity sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==
-
-"@esbuild/win32-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz#0eaf705c941a218a43dba8e09f1df1d6cd2f1f17"
- integrity sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==
+"@esbuild/aix-ppc64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz#7a289c158e29cbf59ea0afc83cc80f06d1c89402"
+ integrity sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==
+
+"@esbuild/android-arm64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz#b8828d9edfa3a92660644eb8de6e4f3c203d7b17"
+ integrity sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==
+
+"@esbuild/android-arm@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.28.0.tgz#5ec1847605e05b5dbe5df90db9ff7e3e4c58dca7"
+ integrity sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==
+
+"@esbuild/android-x64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.28.0.tgz#390642175b88ef82bad4cce03f8ab13fe9b1912e"
+ integrity sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==
+
+"@esbuild/darwin-arm64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz#ae45325960d5950cd6951e4f97396f4e1ff7d8d3"
+ integrity sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==
+
+"@esbuild/darwin-x64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz#c079247d589b6b99449659d94f06951b84bff2e4"
+ integrity sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==
+
+"@esbuild/freebsd-arm64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz#45c456215a486593c94900297202dc11c880a37a"
+ integrity sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==
+
+"@esbuild/freebsd-x64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz#0399494c1c85e4388e9b7040bd60d48f2a5b0d2c"
+ integrity sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==
+
+"@esbuild/linux-arm64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz#d6d9f09ef0de54116bf459a4d53cac7e0952fe39"
+ integrity sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==
+
+"@esbuild/linux-arm@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz#7b42ffa84c288ae94fdc431c1b28a89e3c3b9278"
+ integrity sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==
+
+"@esbuild/linux-ia32@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz#deb15d112ed8dd605346b6b953d23a21ff81253f"
+ integrity sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==
+
+"@esbuild/linux-loong64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz#81fb89d07eecc79b157dea61033757726fce0ca4"
+ integrity sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==
+
+"@esbuild/linux-mips64el@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz#d0e42691b3ff7af9fb2217b70fc01f343bdb62bb"
+ integrity sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==
+
+"@esbuild/linux-ppc64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz#389f3e5e98f17d477c467cc87136e1a076eead87"
+ integrity sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==
+
+"@esbuild/linux-riscv64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz#763bd60d59b242be12da1e67d5729f3024c605fa"
+ integrity sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==
+
+"@esbuild/linux-s390x@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz#aac6061634872e4677de693bce8030d73b1fd055"
+ integrity sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==
+
+"@esbuild/linux-x64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz#4f2917747188fe77632bcec65b2d84b422419779"
+ integrity sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==
+
+"@esbuild/netbsd-arm64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz#814df0ae57a0c386814491b8397eeba82094a947"
+ integrity sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==
+
+"@esbuild/netbsd-x64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz#e01bdf7e60fa1a08e46d46d960b0d9bb8ac210af"
+ integrity sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==
+
+"@esbuild/openbsd-arm64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz#4a15c36aacca68d2d5a4c90b710c06759f4c1ffa"
+ integrity sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==
+
+"@esbuild/openbsd-x64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz#475e6101498a8ecce3008d7c388111d7a27c17bd"
+ integrity sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==
+
+"@esbuild/openharmony-arm64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz#cfdc3957f0b7a69f1bde129aad17fcc2f6fa033e"
+ integrity sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==
+
+"@esbuild/sunos-x64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz#a013c856fecacd1c3aec985c8afe1d1cb017497d"
+ integrity sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==
+
+"@esbuild/win32-arm64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz#eae05e0f35271cad3898b43168d3e9a3bbaf47e5"
+ integrity sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==
+
+"@esbuild/win32-ia32@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz#06161ebc5bf75c08d69feb3c6b22560515913998"
+ integrity sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==
+
+"@esbuild/win32-x64@0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz#04d90d5752b4ce65d2b6ac25eba08ff7624fe07c"
+ integrity sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==
"@eslint-community/eslint-utils@^4.8.0", "@eslint-community/eslint-utils@^4.9.1":
version "4.9.1"
@@ -1522,121 +1522,120 @@
resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98"
integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==
-"@jest/console@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/console/-/console-30.2.0.tgz#c52fcd5b58fdd2e8eb66b2fd8ae56f2f64d05b28"
- integrity sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==
+"@jest/console@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/console/-/console-30.3.0.tgz#42ccc3f995d400a8fe35b8850cfe10a8d4804cdf"
+ integrity sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==
dependencies:
- "@jest/types" "30.2.0"
+ "@jest/types" "30.3.0"
"@types/node" "*"
chalk "^4.1.2"
- jest-message-util "30.2.0"
- jest-util "30.2.0"
+ jest-message-util "30.3.0"
+ jest-util "30.3.0"
slash "^3.0.0"
-"@jest/core@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/core/-/core-30.2.0.tgz#813d59faa5abd5510964a8b3a7b17cc77b775275"
- integrity sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==
+"@jest/core@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/core/-/core-30.3.0.tgz#d06bb8456f35350f6494fd2405bcec4abb97b994"
+ integrity sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==
dependencies:
- "@jest/console" "30.2.0"
+ "@jest/console" "30.3.0"
"@jest/pattern" "30.0.1"
- "@jest/reporters" "30.2.0"
- "@jest/test-result" "30.2.0"
- "@jest/transform" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/reporters" "30.3.0"
+ "@jest/test-result" "30.3.0"
+ "@jest/transform" "30.3.0"
+ "@jest/types" "30.3.0"
"@types/node" "*"
ansi-escapes "^4.3.2"
chalk "^4.1.2"
ci-info "^4.2.0"
exit-x "^0.2.2"
graceful-fs "^4.2.11"
- jest-changed-files "30.2.0"
- jest-config "30.2.0"
- jest-haste-map "30.2.0"
- jest-message-util "30.2.0"
+ jest-changed-files "30.3.0"
+ jest-config "30.3.0"
+ jest-haste-map "30.3.0"
+ jest-message-util "30.3.0"
jest-regex-util "30.0.1"
- jest-resolve "30.2.0"
- jest-resolve-dependencies "30.2.0"
- jest-runner "30.2.0"
- jest-runtime "30.2.0"
- jest-snapshot "30.2.0"
- jest-util "30.2.0"
- jest-validate "30.2.0"
- jest-watcher "30.2.0"
- micromatch "^4.0.8"
- pretty-format "30.2.0"
+ jest-resolve "30.3.0"
+ jest-resolve-dependencies "30.3.0"
+ jest-runner "30.3.0"
+ jest-runtime "30.3.0"
+ jest-snapshot "30.3.0"
+ jest-util "30.3.0"
+ jest-validate "30.3.0"
+ jest-watcher "30.3.0"
+ pretty-format "30.3.0"
slash "^3.0.0"
-"@jest/diff-sequences@30.0.1":
- version "30.0.1"
- resolved "https://registry.yarnpkg.com/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz#0ededeae4d071f5c8ffe3678d15f3a1be09156be"
- integrity sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==
+"@jest/diff-sequences@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz#25b0818d3d83f00b9c7b04e069b8810f9014b143"
+ integrity sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==
-"@jest/environment-jsdom-abstract@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.2.0.tgz#1313f9b3b509c31298c241203161b36622865181"
- integrity sha512-kazxw2L9IPuZpQ0mEt9lu9Z98SqR74xcagANmMBU16X0lS23yPc0+S6hGLUz8kVRlomZEs/5S/Zlpqwf5yu6OQ==
+"@jest/environment-jsdom-abstract@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.3.0.tgz#c97b2bf3ec35336d543c174a758f3dc07478c172"
+ integrity sha512-0hNFs5N6We3DMCwobzI0ydhkY10sT1tZSC0AAiy+0g2Dt/qEWgrcV5BrMxPczhe41cxW4qm6X+jqZaUdpZIajA==
dependencies:
- "@jest/environment" "30.2.0"
- "@jest/fake-timers" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/environment" "30.3.0"
+ "@jest/fake-timers" "30.3.0"
+ "@jest/types" "30.3.0"
"@types/jsdom" "^21.1.7"
"@types/node" "*"
- jest-mock "30.2.0"
- jest-util "30.2.0"
+ jest-mock "30.3.0"
+ jest-util "30.3.0"
-"@jest/environment@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-30.2.0.tgz#1e673cdb8b93ded707cf6631b8353011460831fa"
- integrity sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==
+"@jest/environment@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-30.3.0.tgz#b0657c2944b6ef3352f7b25903cc3a23e6ab70f6"
+ integrity sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==
dependencies:
- "@jest/fake-timers" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/fake-timers" "30.3.0"
+ "@jest/types" "30.3.0"
"@types/node" "*"
- jest-mock "30.2.0"
+ jest-mock "30.3.0"
-"@jest/expect-utils@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-30.2.0.tgz#4f95413d4748454fdb17404bf1141827d15e6011"
- integrity sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==
+"@jest/expect-utils@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-30.3.0.tgz#c45b2da9802ffed33bf43b3e019ddb95e5ad95e8"
+ integrity sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==
dependencies:
"@jest/get-type" "30.1.0"
-"@jest/expect@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-30.2.0.tgz#9a5968499bb8add2bbb09136f69f7df5ddbf3185"
- integrity sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==
+"@jest/expect@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-30.3.0.tgz#08ee7f5b610167b0068743246c0b568f4c40c773"
+ integrity sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==
dependencies:
- expect "30.2.0"
- jest-snapshot "30.2.0"
+ expect "30.3.0"
+ jest-snapshot "30.3.0"
-"@jest/fake-timers@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-30.2.0.tgz#0941ddc28a339b9819542495b5408622dc9e94ec"
- integrity sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==
+"@jest/fake-timers@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-30.3.0.tgz#2b2868130c1d28233a79566874c42cae1c5a70bc"
+ integrity sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==
dependencies:
- "@jest/types" "30.2.0"
- "@sinonjs/fake-timers" "^13.0.0"
+ "@jest/types" "30.3.0"
+ "@sinonjs/fake-timers" "^15.0.0"
"@types/node" "*"
- jest-message-util "30.2.0"
- jest-mock "30.2.0"
- jest-util "30.2.0"
+ jest-message-util "30.3.0"
+ jest-mock "30.3.0"
+ jest-util "30.3.0"
"@jest/get-type@30.1.0":
version "30.1.0"
resolved "https://registry.yarnpkg.com/@jest/get-type/-/get-type-30.1.0.tgz#4fcb4dc2ebcf0811be1c04fd1cb79c2dba431cbc"
integrity sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==
-"@jest/globals@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-30.2.0.tgz#2f4b696d5862664b89c4ee2e49ae24d2bb7e0988"
- integrity sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==
+"@jest/globals@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-30.3.0.tgz#40f4c90e5602629ecda1ca773a8fb21575bb64ea"
+ integrity sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==
dependencies:
- "@jest/environment" "30.2.0"
- "@jest/expect" "30.2.0"
- "@jest/types" "30.2.0"
- jest-mock "30.2.0"
+ "@jest/environment" "30.3.0"
+ "@jest/expect" "30.3.0"
+ "@jest/types" "30.3.0"
+ jest-mock "30.3.0"
"@jest/pattern@30.0.1":
version "30.0.1"
@@ -1646,31 +1645,31 @@
"@types/node" "*"
jest-regex-util "30.0.1"
-"@jest/reporters@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-30.2.0.tgz#a36b28fcbaf0c4595250b108e6f20e363348fd91"
- integrity sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==
+"@jest/reporters@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-30.3.0.tgz#0c1065f6c892665e5a051df22b19df4466ed816b"
+ integrity sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==
dependencies:
"@bcoe/v8-coverage" "^0.2.3"
- "@jest/console" "30.2.0"
- "@jest/test-result" "30.2.0"
- "@jest/transform" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/console" "30.3.0"
+ "@jest/test-result" "30.3.0"
+ "@jest/transform" "30.3.0"
+ "@jest/types" "30.3.0"
"@jridgewell/trace-mapping" "^0.3.25"
"@types/node" "*"
chalk "^4.1.2"
collect-v8-coverage "^1.0.2"
exit-x "^0.2.2"
- glob "^10.3.10"
+ glob "^10.5.0"
graceful-fs "^4.2.11"
istanbul-lib-coverage "^3.0.0"
istanbul-lib-instrument "^6.0.0"
istanbul-lib-report "^3.0.0"
istanbul-lib-source-maps "^5.0.0"
istanbul-reports "^3.1.3"
- jest-message-util "30.2.0"
- jest-util "30.2.0"
- jest-worker "30.2.0"
+ jest-message-util "30.3.0"
+ jest-util "30.3.0"
+ jest-worker "30.3.0"
slash "^3.0.0"
string-length "^4.0.2"
v8-to-istanbul "^9.0.1"
@@ -1682,12 +1681,12 @@
dependencies:
"@sinclair/typebox" "^0.34.0"
-"@jest/snapshot-utils@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz#387858eb90c2f98f67bff327435a532ac5309fbe"
- integrity sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==
+"@jest/snapshot-utils@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz#ca003c91a3e1e4e4956dee716a2aaf04b6707f31"
+ integrity sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==
dependencies:
- "@jest/types" "30.2.0"
+ "@jest/types" "30.3.0"
chalk "^4.1.2"
graceful-fs "^4.2.11"
natural-compare "^1.4.0"
@@ -1701,51 +1700,50 @@
callsites "^3.1.0"
graceful-fs "^4.2.11"
-"@jest/test-result@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-30.2.0.tgz#9c0124377fb7996cdffb86eda3dbc56eacab363d"
- integrity sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==
+"@jest/test-result@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-30.3.0.tgz#cd8882d683d467fcffb98c09501a65687a76aae9"
+ integrity sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==
dependencies:
- "@jest/console" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/console" "30.3.0"
+ "@jest/types" "30.3.0"
"@types/istanbul-lib-coverage" "^2.0.6"
collect-v8-coverage "^1.0.2"
-"@jest/test-sequencer@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz#bf0066bc72e176d58f5dfa7f212b6e7eee44f221"
- integrity sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==
+"@jest/test-sequencer@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz#27002b2093f4e0d9e0e1ebb0bc274a242fdadc14"
+ integrity sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==
dependencies:
- "@jest/test-result" "30.2.0"
+ "@jest/test-result" "30.3.0"
graceful-fs "^4.2.11"
- jest-haste-map "30.2.0"
+ jest-haste-map "30.3.0"
slash "^3.0.0"
-"@jest/transform@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-30.2.0.tgz#54bef1a4510dcbd58d5d4de4fe2980a63077ef2a"
- integrity sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==
+"@jest/transform@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-30.3.0.tgz#9e6f78ffa205449bf956e269fd707c160f47ce2f"
+ integrity sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==
dependencies:
"@babel/core" "^7.27.4"
- "@jest/types" "30.2.0"
+ "@jest/types" "30.3.0"
"@jridgewell/trace-mapping" "^0.3.25"
babel-plugin-istanbul "^7.0.1"
chalk "^4.1.2"
convert-source-map "^2.0.0"
fast-json-stable-stringify "^2.1.0"
graceful-fs "^4.2.11"
- jest-haste-map "30.2.0"
+ jest-haste-map "30.3.0"
jest-regex-util "30.0.1"
- jest-util "30.2.0"
- micromatch "^4.0.8"
+ jest-util "30.3.0"
pirates "^4.0.7"
slash "^3.0.0"
write-file-atomic "^5.0.1"
-"@jest/types@30.2.0":
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/@jest/types/-/types-30.2.0.tgz#1c678a7924b8f59eafd4c77d56b6d0ba976d62b8"
- integrity sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==
+"@jest/types@30.3.0":
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/@jest/types/-/types-30.3.0.tgz#cada800d323cb74945c24ac74615fdb312a6c85f"
+ integrity sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==
dependencies:
"@jest/pattern" "30.0.1"
"@jest/schemas" "30.0.5"
@@ -2102,10 +2100,10 @@
dependencies:
type-detect "4.0.8"
-"@sinonjs/fake-timers@^13.0.0":
- version "13.0.5"
- resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz#36b9dbc21ad5546486ea9173d6bea063eb1717d5"
- integrity sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==
+"@sinonjs/fake-timers@^15.0.0":
+ version "15.3.2"
+ resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz#afecc36681e26aab9e0fe809fd9ad578096a3058"
+ integrity sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==
dependencies:
"@sinonjs/commons" "^3.0.1"
@@ -2366,10 +2364,10 @@
dependencies:
"@types/unist" "*"
-"@types/node@*", "@types/node@>=13.7.0", "@types/node@^22.19.15":
- version "22.19.15"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.15.tgz#6091d99fdf7c08cb57dc8b1345d407ba9a1df576"
- integrity sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==
+"@types/node@*", "@types/node@>=13.7.0", "@types/node@^22.19.17":
+ version "22.19.17"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.17.tgz#09c71fb34ba2510f8ac865361b1fcb9552b8a581"
+ integrity sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==
dependencies:
undici-types "~6.21.0"
@@ -2417,11 +2415,6 @@
dependencies:
"@types/react" "*"
-"@types/react-transition-group@^4.4.5":
- version "4.4.12"
- resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044"
- integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==
-
"@types/react@*", "@types/react@^18.3.28":
version "18.3.28"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.28.tgz#0a85b1a7243b4258d9f626f43797ba18eb5f8781"
@@ -2489,160 +2482,100 @@
dependencies:
"@types/yargs-parser" "*"
-"@typescript-eslint/eslint-plugin@8.56.0", "@typescript-eslint/eslint-plugin@^8.56.0":
- version "8.56.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz#5aec3db807a6b8437ea5d5ebf7bd16b4119aba8d"
- integrity sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==
+"@typescript-eslint/eslint-plugin@8.59.0", "@typescript-eslint/eslint-plugin@^8.59.0":
+ version "8.59.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.0.tgz#fcbe76b693ce2412410cf4d48aefd617d345f2d9"
+ integrity sha512-HyAZtpdkgZwpq8Sz3FSUvCR4c+ScbuWa9AksK2Jweub7w4M3yTz4O11AqVJzLYjy/B9ZWPyc81I+mOdJU/bDQw==
dependencies:
"@eslint-community/regexpp" "^4.12.2"
- "@typescript-eslint/scope-manager" "8.56.0"
- "@typescript-eslint/type-utils" "8.56.0"
- "@typescript-eslint/utils" "8.56.0"
- "@typescript-eslint/visitor-keys" "8.56.0"
+ "@typescript-eslint/scope-manager" "8.59.0"
+ "@typescript-eslint/type-utils" "8.59.0"
+ "@typescript-eslint/utils" "8.59.0"
+ "@typescript-eslint/visitor-keys" "8.59.0"
ignore "^7.0.5"
natural-compare "^1.4.0"
- ts-api-utils "^2.4.0"
+ ts-api-utils "^2.5.0"
-"@typescript-eslint/parser@8.56.0", "@typescript-eslint/parser@^8.56.0":
- version "8.56.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.56.0.tgz#8ecff1678b8b1a742d29c446ccf5eeea7f971d72"
- integrity sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==
+"@typescript-eslint/parser@8.59.0", "@typescript-eslint/parser@^8.59.0":
+ version "8.59.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.59.0.tgz#57a138280b3ceaf07904fbd62c433d5cc1ee1573"
+ integrity sha512-TI1XGwKbDpo9tRW8UDIXCOeLk55qe9ZFGs8MTKU6/M08HWTw52DD/IYhfQtOEhEdPhLMT26Ka/x7p70nd3dzDg==
dependencies:
- "@typescript-eslint/scope-manager" "8.56.0"
- "@typescript-eslint/types" "8.56.0"
- "@typescript-eslint/typescript-estree" "8.56.0"
- "@typescript-eslint/visitor-keys" "8.56.0"
+ "@typescript-eslint/scope-manager" "8.59.0"
+ "@typescript-eslint/types" "8.59.0"
+ "@typescript-eslint/typescript-estree" "8.59.0"
+ "@typescript-eslint/visitor-keys" "8.59.0"
debug "^4.4.3"
-"@typescript-eslint/project-service@8.56.0":
- version "8.56.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.56.0.tgz#bb8562fecd8f7922e676fc6a1189c20dd7991d73"
- integrity sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==
+"@typescript-eslint/project-service@8.59.0":
+ version "8.59.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.59.0.tgz#914bf62069d870faa0389ffd725774a200f511bf"
+ integrity sha512-Lw5ITrR5s5TbC19YSvlr63ZfLaJoU6vtKTHyB0GQOpX0W7d5/Ir6vUahWi/8Sps/nOukZQ0IB3SmlxZnjaKVnw==
dependencies:
- "@typescript-eslint/tsconfig-utils" "^8.56.0"
- "@typescript-eslint/types" "^8.56.0"
+ "@typescript-eslint/tsconfig-utils" "^8.59.0"
+ "@typescript-eslint/types" "^8.59.0"
debug "^4.4.3"
-"@typescript-eslint/project-service@8.56.1":
- version "8.56.1"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.56.1.tgz#65c8d645f028b927bfc4928593b54e2ecd809244"
- integrity sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==
- dependencies:
- "@typescript-eslint/tsconfig-utils" "^8.56.1"
- "@typescript-eslint/types" "^8.56.1"
- debug "^4.4.3"
-
-"@typescript-eslint/scope-manager@8.56.0":
- version "8.56.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz#604030a4c6433df3728effdd441d47f45a86edb4"
- integrity sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==
- dependencies:
- "@typescript-eslint/types" "8.56.0"
- "@typescript-eslint/visitor-keys" "8.56.0"
-
-"@typescript-eslint/scope-manager@8.56.1", "@typescript-eslint/scope-manager@^8.56.0":
- version "8.56.1"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz#254df93b5789a871351335dd23e20bc164060f24"
- integrity sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==
+"@typescript-eslint/scope-manager@8.59.0", "@typescript-eslint/scope-manager@^8.56.0":
+ version "8.59.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.59.0.tgz#f71be268bd31da1c160815c689e4dde7c9bc9e8e"
+ integrity sha512-UzR16Ut8IpA3Mc4DbgAShlPPkVm8xXMWafXxB0BocaVRHs8ZGakAxGRskF7FId3sdk9lgGD73GSFaWmWFDE4dg==
dependencies:
- "@typescript-eslint/types" "8.56.1"
- "@typescript-eslint/visitor-keys" "8.56.1"
-
-"@typescript-eslint/tsconfig-utils@8.56.0":
- version "8.56.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz#2538ce83cbc376e685487960cbb24b65fe2abc4e"
- integrity sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==
+ "@typescript-eslint/types" "8.59.0"
+ "@typescript-eslint/visitor-keys" "8.59.0"
-"@typescript-eslint/tsconfig-utils@8.56.1", "@typescript-eslint/tsconfig-utils@^8.56.0", "@typescript-eslint/tsconfig-utils@^8.56.1":
- version "8.56.1"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz#1afa830b0fada5865ddcabdc993b790114a879b7"
- integrity sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==
+"@typescript-eslint/tsconfig-utils@8.59.0", "@typescript-eslint/tsconfig-utils@^8.59.0":
+ version "8.59.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.0.tgz#1276077f5ad77e384446ea28a2474e8f8be1af41"
+ integrity sha512-91Sbl3s4Kb3SybliIY6muFBmHVv+pYXfybC4Oolp3dvk8BvIE3wOPc+403CWIT7mJNkfQRGtdqghzs2+Z91Tqg==
-"@typescript-eslint/type-utils@8.56.0":
- version "8.56.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz#72b4edc1fc73988998f1632b3ec99c2a66eaac6e"
- integrity sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==
+"@typescript-eslint/type-utils@8.59.0":
+ version "8.59.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.59.0.tgz#2834ea3b179cedfc9244dcd4f74105a27751a439"
+ integrity sha512-3TRiZaQSltGqGeNrJzzr1+8YcEobKH9rHnqIp/1psfKFmhRQDNMGP5hBufanYTGznwShzVLs3Mz+gDN7HkWfXg==
dependencies:
- "@typescript-eslint/types" "8.56.0"
- "@typescript-eslint/typescript-estree" "8.56.0"
- "@typescript-eslint/utils" "8.56.0"
+ "@typescript-eslint/types" "8.59.0"
+ "@typescript-eslint/typescript-estree" "8.59.0"
+ "@typescript-eslint/utils" "8.59.0"
debug "^4.4.3"
- ts-api-utils "^2.4.0"
-
-"@typescript-eslint/types@8.56.0":
- version "8.56.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.56.0.tgz#a2444011b9a98ca13d70411d2cbfed5443b3526a"
- integrity sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==
-
-"@typescript-eslint/types@8.56.1", "@typescript-eslint/types@^8.56.0", "@typescript-eslint/types@^8.56.1":
- version "8.56.1"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.56.1.tgz#975e5942bf54895291337c91b9191f6eb0632ab9"
- integrity sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==
-
-"@typescript-eslint/typescript-estree@8.56.0":
- version "8.56.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz#fadbc74c14c5bac947db04980ff58bb178701c2e"
- integrity sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==
- dependencies:
- "@typescript-eslint/project-service" "8.56.0"
- "@typescript-eslint/tsconfig-utils" "8.56.0"
- "@typescript-eslint/types" "8.56.0"
- "@typescript-eslint/visitor-keys" "8.56.0"
- debug "^4.4.3"
- minimatch "^9.0.5"
- semver "^7.7.3"
- tinyglobby "^0.2.15"
- ts-api-utils "^2.4.0"
-
-"@typescript-eslint/typescript-estree@8.56.1":
- version "8.56.1"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz#3b9e57d8129a860c50864c42188f761bdef3eab0"
- integrity sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==
- dependencies:
- "@typescript-eslint/project-service" "8.56.1"
- "@typescript-eslint/tsconfig-utils" "8.56.1"
- "@typescript-eslint/types" "8.56.1"
- "@typescript-eslint/visitor-keys" "8.56.1"
+ ts-api-utils "^2.5.0"
+
+"@typescript-eslint/types@8.59.0", "@typescript-eslint/types@^8.59.0":
+ version "8.59.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.59.0.tgz#cfcc643c6e879016479775850d86d84c14492738"
+ integrity sha512-nLzdsT1gdOgFxxxwrlNVUBzSNBEEHJ86bblmk4QAS6stfig7rcJzWKqCyxFy3YRRHXDWEkb2NralA1nOYkkm/A==
+
+"@typescript-eslint/typescript-estree@8.59.0":
+ version "8.59.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.0.tgz#feba58a70ab6ea7ac53a2f3ae900db28ce3454c2"
+ integrity sha512-O9Re9P1BmBLFJyikRbQpLku/QA3/AueZNO9WePLBwQrvkixTmDe8u76B6CYUAITRl/rHawggEqUGn5QIkVRLMw==
+ dependencies:
+ "@typescript-eslint/project-service" "8.59.0"
+ "@typescript-eslint/tsconfig-utils" "8.59.0"
+ "@typescript-eslint/types" "8.59.0"
+ "@typescript-eslint/visitor-keys" "8.59.0"
debug "^4.4.3"
minimatch "^10.2.2"
semver "^7.7.3"
tinyglobby "^0.2.15"
- ts-api-utils "^2.4.0"
+ ts-api-utils "^2.5.0"
-"@typescript-eslint/utils@8.56.0":
- version "8.56.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.56.0.tgz#063ce6f702ec603de1b83ee795ed5e877d6f7841"
- integrity sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==
+"@typescript-eslint/utils@8.59.0", "@typescript-eslint/utils@^8.0.0", "@typescript-eslint/utils@^8.56.0":
+ version "8.59.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.59.0.tgz#f50df9bd6967881ef64fba62230111153179ead5"
+ integrity sha512-I1R/K7V07XsMJ12Oaxg/O9GfrysGTmCRhvZJBv0RE0NcULMzjqVpR5kRRQjHsz3J/bElU7HwCO7zkqL+MSUz+g==
dependencies:
"@eslint-community/eslint-utils" "^4.9.1"
- "@typescript-eslint/scope-manager" "8.56.0"
- "@typescript-eslint/types" "8.56.0"
- "@typescript-eslint/typescript-estree" "8.56.0"
+ "@typescript-eslint/scope-manager" "8.59.0"
+ "@typescript-eslint/types" "8.59.0"
+ "@typescript-eslint/typescript-estree" "8.59.0"
-"@typescript-eslint/utils@^8.0.0", "@typescript-eslint/utils@^8.56.0":
- version "8.56.1"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.56.1.tgz#5a86acaf9f1b4c4a85a42effb217f73059f6deb7"
- integrity sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==
+"@typescript-eslint/visitor-keys@8.59.0":
+ version "8.59.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.0.tgz#2e80de30e7e944ed4bd47d751e37dcb04db03795"
+ integrity sha512-/uejZt4dSere1bx12WLlPfv8GktzcaDtuJ7s42/HEZ5zGj9oxRaD4bj7qwSunXkf+pbAhFt2zjpHYUiT5lHf0Q==
dependencies:
- "@eslint-community/eslint-utils" "^4.9.1"
- "@typescript-eslint/scope-manager" "8.56.1"
- "@typescript-eslint/types" "8.56.1"
- "@typescript-eslint/typescript-estree" "8.56.1"
-
-"@typescript-eslint/visitor-keys@8.56.0":
- version "8.56.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz#7d6592ab001827d3ce052155edf7ecad19688d7d"
- integrity sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==
- dependencies:
- "@typescript-eslint/types" "8.56.0"
- eslint-visitor-keys "^5.0.0"
-
-"@typescript-eslint/visitor-keys@8.56.1":
- version "8.56.1"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz#50e03475c33a42d123dc99e63acf1841c0231f87"
- integrity sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==
- dependencies:
- "@typescript-eslint/types" "8.56.1"
+ "@typescript-eslint/types" "8.59.0"
eslint-visitor-keys "^5.0.0"
"@ungap/structured-clone@^1.3.0":
@@ -3103,15 +3036,15 @@ available-typed-arrays@^1.0.7:
dependencies:
possible-typed-array-names "^1.0.0"
-babel-jest@30.2.0, babel-jest@^30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-30.2.0.tgz#fd44a1ec9552be35ead881f7381faa7d8f3b95ac"
- integrity sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==
+babel-jest@30.3.0, babel-jest@^30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-30.3.0.tgz#3ff5553fa3bcbb8738d2d7335a4dbdc3bd1a0eb5"
+ integrity sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==
dependencies:
- "@jest/transform" "30.2.0"
+ "@jest/transform" "30.3.0"
"@types/babel__core" "^7.20.5"
babel-plugin-istanbul "^7.0.1"
- babel-preset-jest "30.2.0"
+ babel-preset-jest "30.3.0"
chalk "^4.1.2"
graceful-fs "^4.2.11"
slash "^3.0.0"
@@ -3127,17 +3060,17 @@ babel-plugin-istanbul@^7.0.1:
istanbul-lib-instrument "^6.0.2"
test-exclude "^6.0.0"
-babel-plugin-jest-hoist@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz#94c250d36b43f95900f3a219241e0f4648191ce2"
- integrity sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==
+babel-plugin-jest-hoist@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz#235ad714a45c18b12566becf439e1c604e277015"
+ integrity sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==
dependencies:
"@types/babel__core" "^7.20.5"
-babel-plugin-module-resolver@^5.0.2:
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.2.tgz#cdeac5d4aaa3b08dd1ac23ddbf516660ed2d293e"
- integrity sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg==
+babel-plugin-module-resolver@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.3.tgz#13f03cf29048ad7e0239e6a1c4dcc669d199f394"
+ integrity sha512-h8h6H71ZvdLJZxZrYkaeR30BojTaV7O9GfqacY14SNj5CNB8ocL9tydNzTC0JrnNN7vY3eJhwCmkDj7tuEUaqQ==
dependencies:
find-babel-config "^2.1.1"
glob "^9.3.3"
@@ -3190,12 +3123,12 @@ babel-preset-current-node-syntax@^1.2.0:
"@babel/plugin-syntax-private-property-in-object" "^7.14.5"
"@babel/plugin-syntax-top-level-await" "^7.14.5"
-babel-preset-jest@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz#04717843e561347781d6d7f69c81e6bcc3ed11ce"
- integrity sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==
+babel-preset-jest@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz#21cf3d19a6f5e9924426c879ee0b7f092636d043"
+ integrity sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==
dependencies:
- babel-plugin-jest-hoist "30.2.0"
+ babel-plugin-jest-hoist "30.3.0"
babel-preset-current-node-syntax "^1.2.0"
bail@^2.0.0:
@@ -3208,11 +3141,6 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
-balanced-match@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-3.0.1.tgz#e854b098724b15076384266497392a271f4a26a0"
- integrity sha512-vjtV3hiLqYDNRoiAv0zC4QaGAMPomEoq83PRmYIofPswwZurCeWR5LByXm7SyoL0Zh5+2z0+HC7jG8gSZJUh0w==
-
balanced-match@^4.0.2:
version "4.0.4"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a"
@@ -3223,10 +3151,10 @@ base64-js@^1.3.1:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
-baseline-browser-mapping@^2.9.0:
- version "2.9.10"
- resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.10.tgz#099221e89b30ec784675af076fbd4a93e58b53c3"
- integrity sha512-2VIKvDx8Z1a9rTB2eCkdPE5nSe28XnA+qivGnWHoB40hMMt/h1hSz0960Zqsn6ZyxWXUie0EBdElKv8may20AA==
+baseline-browser-mapping@^2.10.12:
+ version "2.10.18"
+ resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.18.tgz#565745085ba7743af7d4072707ad132db3a5a42f"
+ integrity sha512-VSnGQAOLtP5mib/DPyg2/t+Tlv65NTBz83BJBJvmLVHHuKJVaDOBvJJykiT5TR++em5nfAySPccDZDa4oSrn8A==
basic-auth@^2.0.1, basic-auth@~2.0.1:
version "2.0.1"
@@ -3318,16 +3246,16 @@ browserslist-to-esbuild@^2.1.1:
dependencies:
meow "^13.0.0"
-browserslist@^4.24.0, browserslist@^4.28.1:
- version "4.28.1"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95"
- integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==
+browserslist@^4.24.0, browserslist@^4.28.1, browserslist@^4.28.2:
+ version "4.28.2"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.2.tgz#f50b65362ef48974ca9f50b3680566d786b811d2"
+ integrity sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==
dependencies:
- baseline-browser-mapping "^2.9.0"
- caniuse-lite "^1.0.30001759"
- electron-to-chromium "^1.5.263"
- node-releases "^2.0.27"
- update-browserslist-db "^1.2.0"
+ baseline-browser-mapping "^2.10.12"
+ caniuse-lite "^1.0.30001782"
+ electron-to-chromium "^1.5.328"
+ node-releases "^2.0.36"
+ update-browserslist-db "^1.2.3"
bser@2.1.1:
version "2.1.1"
@@ -3501,10 +3429,10 @@ camelcase@^8.0.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-8.0.0.tgz#c0d36d418753fb6ad9c5e0437579745c1c14a534"
integrity sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==
-caniuse-lite@^1.0.30001759, caniuse-lite@^1.0.30001770:
- version "1.0.30001770"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz#4dc47d3b263a50fbb243448034921e0a88591a84"
- integrity sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==
+caniuse-lite@^1.0.30001782, caniuse-lite@^1.0.30001788:
+ version "1.0.30001788"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz#31e97d1bfec332b3f2d7eea7781460c97629b3bf"
+ integrity sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==
ccount@^2.0.0:
version "2.0.1"
@@ -3856,10 +3784,10 @@ core-js-compat@^3.48.0:
dependencies:
browserslist "^4.28.1"
-core-js@^3.48.0:
- version "3.48.0"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.48.0.tgz#1f813220a47bbf0e667e3885c36cd6f0593bf14d"
- integrity sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==
+core-js@^3.49.0:
+ version "3.49.0"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.49.0.tgz#8b4d520ac034311fa21aa616f017ada0e0dbbddd"
+ integrity sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==
core-util-is@~1.0.0:
version "1.0.3"
@@ -3877,10 +3805,10 @@ cosmiconfig@^7.0.0:
path-type "^4.0.0"
yaml "^1.10.0"
-cosmiconfig@^9.0.0:
- version "9.0.0"
- resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz#34c3fc58287b915f3ae905ab6dc3de258b55ad9d"
- integrity sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==
+cosmiconfig@^9.0.0, cosmiconfig@^9.0.1:
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.1.tgz#df110631a8547b5d1a98915271986f06e3011379"
+ integrity sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==
dependencies:
env-paths "^2.2.1"
import-fresh "^3.3.0"
@@ -3926,18 +3854,18 @@ crypto-random-string@^4.0.0:
dependencies:
type-fest "^1.0.1"
-css-functions-list@^3.2.3:
- version "3.2.3"
- resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.2.3.tgz#95652b0c24f0f59b291a9fc386041a19d4f40dbe"
- integrity sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==
+css-functions-list@^3.3.3:
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.3.3.tgz#c4ab5008659de2e3baf3752c8fdef7662f3ffe23"
+ integrity sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==
-css-tree@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-3.1.0.tgz#7aabc035f4e66b5c86f54570d55e05b1346eb0fd"
- integrity sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==
+css-tree@^3.2.1:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-3.2.1.tgz#86cac7011561272b30e6b1e042ba6ce047aa7518"
+ integrity sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==
dependencies:
- mdn-data "2.12.2"
- source-map-js "^1.0.1"
+ mdn-data "2.27.1"
+ source-map-js "^1.2.1"
css.escape@^1.5.1:
version "1.5.1"
@@ -3957,7 +3885,7 @@ cssstyle@^4.2.1:
"@asamuzakjp/css-color" "^3.2.0"
rrweb-cssom "^0.8.0"
-csstype@^3.0.2, csstype@^3.2.2:
+csstype@^3.2.2:
version "3.2.3"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a"
integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==
@@ -4195,10 +4123,10 @@ devtools-license-check@^0.9.0:
dependencies:
license-checker "^9.0.3"
-devtools-reps@^0.27.4:
- version "0.27.4"
- resolved "https://registry.yarnpkg.com/devtools-reps/-/devtools-reps-0.27.4.tgz#71cd2e595a1fd51164b18e2bbf15d6f83e747d8b"
- integrity sha512-YQJy8Quz6H3BNcUYgmjPWYX736owTIU6MKE/k1WuArPtzkyWbP9EEQFgir48GSqc/w5QGuDDmBF4LhM9AS7mcg==
+devtools-reps@^0.27.6:
+ version "0.27.6"
+ resolved "https://registry.yarnpkg.com/devtools-reps/-/devtools-reps-0.27.6.tgz#26aa682cfd058e171064bc86da6590e80785933f"
+ integrity sha512-ukQco/6e3nmTOk/qDnW7VuMga6XAlshJ/aBsCfq6ZTmaqJG2YybK7STV6oEiy2vi1U/YGQpg46mhPNx4fKytzw==
dependencies:
prop-types "^15.7.2"
react "^16.8.6"
@@ -4242,14 +4170,6 @@ dom-accessibility-api@^0.6.3:
resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz#993e925cc1d73f2c662e7d75dd5a5445259a8fd8"
integrity sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==
-dom-helpers@^5.0.1:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b"
- integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==
- dependencies:
- "@babel/runtime" "^7.8.7"
- csstype "^3.0.2"
-
dot-prop@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083"
@@ -4295,10 +4215,10 @@ ejs@^3.1.6:
dependencies:
jake "^10.8.5"
-electron-to-chromium@^1.5.263:
- version "1.5.267"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz#5d84f2df8cdb6bfe7e873706bb21bd4bfb574dc7"
- integrity sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==
+electron-to-chromium@^1.5.328:
+ version "1.5.335"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.335.tgz#0b957cea44ef86795c227c616d16b4803d119daa"
+ integrity sha512-q9n5T4BR4Xwa2cwbrwcsDJtHD/enpQ5S1xF1IAtdqf5AAgqDFmR/aakqH3ChFdqd/QXJhS3rnnXFtexU7rax6Q==
emittery@^0.13.1:
version "0.13.1"
@@ -4489,37 +4409,37 @@ esbuild-plugin-wasm@^1.1.0:
resolved "https://registry.yarnpkg.com/esbuild-plugin-wasm/-/esbuild-plugin-wasm-1.1.0.tgz#062c0e62c266e94165c66ebcbb5852a1cdbfd7cd"
integrity sha512-0bQ6+1tUbySSnxzn5jnXHMDvYnT0cN/Wd4Syk8g/sqAIJUg7buTIi22svS3Qz6ssx895NT+TgLPb33xi1OkZig==
-esbuild@^0.27.0:
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.27.3.tgz#5859ca8e70a3af956b26895ce4954d7e73bd27a8"
- integrity sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==
+esbuild@^0.28.0:
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.28.0.tgz#5dee347ffb3e3874212a35a69836b077b1ce6d96"
+ integrity sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==
optionalDependencies:
- "@esbuild/aix-ppc64" "0.27.3"
- "@esbuild/android-arm" "0.27.3"
- "@esbuild/android-arm64" "0.27.3"
- "@esbuild/android-x64" "0.27.3"
- "@esbuild/darwin-arm64" "0.27.3"
- "@esbuild/darwin-x64" "0.27.3"
- "@esbuild/freebsd-arm64" "0.27.3"
- "@esbuild/freebsd-x64" "0.27.3"
- "@esbuild/linux-arm" "0.27.3"
- "@esbuild/linux-arm64" "0.27.3"
- "@esbuild/linux-ia32" "0.27.3"
- "@esbuild/linux-loong64" "0.27.3"
- "@esbuild/linux-mips64el" "0.27.3"
- "@esbuild/linux-ppc64" "0.27.3"
- "@esbuild/linux-riscv64" "0.27.3"
- "@esbuild/linux-s390x" "0.27.3"
- "@esbuild/linux-x64" "0.27.3"
- "@esbuild/netbsd-arm64" "0.27.3"
- "@esbuild/netbsd-x64" "0.27.3"
- "@esbuild/openbsd-arm64" "0.27.3"
- "@esbuild/openbsd-x64" "0.27.3"
- "@esbuild/openharmony-arm64" "0.27.3"
- "@esbuild/sunos-x64" "0.27.3"
- "@esbuild/win32-arm64" "0.27.3"
- "@esbuild/win32-ia32" "0.27.3"
- "@esbuild/win32-x64" "0.27.3"
+ "@esbuild/aix-ppc64" "0.28.0"
+ "@esbuild/android-arm" "0.28.0"
+ "@esbuild/android-arm64" "0.28.0"
+ "@esbuild/android-x64" "0.28.0"
+ "@esbuild/darwin-arm64" "0.28.0"
+ "@esbuild/darwin-x64" "0.28.0"
+ "@esbuild/freebsd-arm64" "0.28.0"
+ "@esbuild/freebsd-x64" "0.28.0"
+ "@esbuild/linux-arm" "0.28.0"
+ "@esbuild/linux-arm64" "0.28.0"
+ "@esbuild/linux-ia32" "0.28.0"
+ "@esbuild/linux-loong64" "0.28.0"
+ "@esbuild/linux-mips64el" "0.28.0"
+ "@esbuild/linux-ppc64" "0.28.0"
+ "@esbuild/linux-riscv64" "0.28.0"
+ "@esbuild/linux-s390x" "0.28.0"
+ "@esbuild/linux-x64" "0.28.0"
+ "@esbuild/netbsd-arm64" "0.28.0"
+ "@esbuild/netbsd-x64" "0.28.0"
+ "@esbuild/openbsd-arm64" "0.28.0"
+ "@esbuild/openbsd-x64" "0.28.0"
+ "@esbuild/openharmony-arm64" "0.28.0"
+ "@esbuild/sunos-x64" "0.28.0"
+ "@esbuild/win32-arm64" "0.28.0"
+ "@esbuild/win32-ia32" "0.28.0"
+ "@esbuild/win32-x64" "0.28.0"
escalade@^3.1.1, escalade@^3.2.0:
version "3.2.0"
@@ -4620,10 +4540,10 @@ eslint-plugin-jest-formatting@^3.1.0:
resolved "https://registry.yarnpkg.com/eslint-plugin-jest-formatting/-/eslint-plugin-jest-formatting-3.1.0.tgz#b26dd5a40f432b642dcc880021a771bb1c93dcd2"
integrity sha512-XyysraZ1JSgGbLSDxjj5HzKKh0glgWf+7CkqxbTqb7zEhW7X2WHo5SBQ8cGhnszKN+2Lj3/oevBlHNbHezoc/A==
-eslint-plugin-jest@^29.15.0:
- version "29.15.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-29.15.0.tgz#58a5917a88244f7536ae10c68b5bd58d407896f0"
- integrity sha512-ZCGr7vTH2WSo2hrK5oM2RULFmMruQ7W3cX7YfwoTiPfzTGTFBMmrVIz45jZHd++cGKj/kWf02li/RhTGcANJSA==
+eslint-plugin-jest@^29.15.2:
+ version "29.15.2"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-29.15.2.tgz#e4ecd1c88dfb8a62b4a0857724792c2aab7e9b6d"
+ integrity sha512-kEN4r9RZl1xcsb4arGq89LrcVdOUFII/JSCwtTPJyv16mDwmPrcuEQwpxqZHeINvcsd7oK5O/rhdGlxFRaZwvQ==
dependencies:
"@typescript-eslint/utils" "^8.0.0"
@@ -4651,10 +4571,10 @@ eslint-plugin-react@^7.37.5:
string.prototype.matchall "^4.0.12"
string.prototype.repeat "^1.0.0"
-eslint-plugin-testing-library@^7.16.0:
- version "7.16.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-7.16.0.tgz#ac8dd5e4069e9264d997079b4cb5f45e79d2b8a7"
- integrity sha512-lHZI6/Olb2oZqxd1+s1nOLCtL2PXKrc1ERz6oDbUKS0xZAMFH3Fy6wJo75z3pXTop3BV6+loPi2MSjIYt3vpAg==
+eslint-plugin-testing-library@^7.16.2:
+ version "7.16.2"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-7.16.2.tgz#b59738085db6bb3b2fed0294c70c9098b45bbf90"
+ integrity sha512-8gleGnQXK2ZA3hHwjCwpYTZvM+9VsrJ+/9kDI8CjqAQGAdMQOdn/rJNu7ZySENuiWlGKQWyZJ4ZjEg2zamaRHw==
dependencies:
"@typescript-eslint/scope-manager" "^8.56.0"
"@typescript-eslint/utils" "^8.56.0"
@@ -4844,17 +4764,17 @@ exit-x@^0.2.2:
resolved "https://registry.yarnpkg.com/exit-x/-/exit-x-0.2.2.tgz#1f9052de3b8d99a696b10dad5bced9bdd5c3aa64"
integrity sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==
-expect@30.2.0, expect@^30.0.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/expect/-/expect-30.2.0.tgz#d4013bed267013c14bc1199cec8aa57cee9b5869"
- integrity sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==
+expect@30.3.0, expect@^30.0.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/expect/-/expect-30.3.0.tgz#1b82111517d1ab030f3db0cf1b4061c8aa644f61"
+ integrity sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==
dependencies:
- "@jest/expect-utils" "30.2.0"
+ "@jest/expect-utils" "30.3.0"
"@jest/get-type" "30.1.0"
- jest-matcher-utils "30.2.0"
- jest-message-util "30.2.0"
- jest-mock "30.2.0"
- jest-util "30.2.0"
+ jest-matcher-utils "30.3.0"
+ jest-message-util "30.3.0"
+ jest-mock "30.3.0"
+ jest-util "30.3.0"
extend@^3.0.0:
version "3.0.2"
@@ -5260,10 +5180,10 @@ glob-to-regexp@^0.4.1:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
-glob@^10.3.10:
- version "10.4.5"
- resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956"
- integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==
+glob@^10.5.0:
+ version "10.5.0"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-10.5.0.tgz#8ec0355919cd3338c28428a23d4f24ecc5fe738c"
+ integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==
dependencies:
foreground-child "^3.1.0"
jackspeak "^3.1.2"
@@ -5361,10 +5281,10 @@ globals@^14.0.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
-globals@^17.4.0:
- version "17.4.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-17.4.0.tgz#33d7d297ed1536b388a0e2f4bcd0ff19c8ff91b5"
- integrity sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==
+globals@^17.5.0:
+ version "17.5.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-17.5.0.tgz#a82c641d898f8dfbe0e81f66fdff7d0de43f88c6"
+ integrity sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==
globalthis@^1.0.4:
version "1.0.4"
@@ -5386,10 +5306,10 @@ globby@^11.0.3:
merge2 "^1.4.1"
slash "^3.0.0"
-globby@^16.1.0:
- version "16.1.0"
- resolved "https://registry.yarnpkg.com/globby/-/globby-16.1.0.tgz#71ab8199e4fc1c4c21a59bd14ec0f31c71d7d7d4"
- integrity sha512-+A4Hq7m7Ze592k9gZRy4gJ27DrXRNnC1vPjxTt1qQxEY8RxagBkBxivkCwg7FxSTG0iLLEMaUx13oOr0R2/qcQ==
+globby@^16.1.1:
+ version "16.2.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-16.2.0.tgz#6ab1351fbac1d9b9e47ed423814c2ad41af308ea"
+ integrity sha512-QrJia2qDf5BB/V6HYlDTs0I0lBahyjLzpGQg3KT7FnCdTonAyPy2RtY802m2k4ALx6Dp752f82WsOczEVr3l6Q==
dependencies:
"@sindresorhus/merge-streams" "^4.0.0"
fast-glob "^3.3.3"
@@ -6433,96 +6353,95 @@ jake@^10.8.5:
filelist "^1.0.1"
minimatch "^3.0.4"
-jest-changed-files@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-30.2.0.tgz#602266e478ed554e1e1469944faa7efd37cee61c"
- integrity sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==
+jest-changed-files@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-30.3.0.tgz#055849df695f9a9fcde0ae44024f815bbc627f3a"
+ integrity sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==
dependencies:
execa "^5.1.1"
- jest-util "30.2.0"
+ jest-util "30.3.0"
p-limit "^3.1.0"
-jest-circus@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-30.2.0.tgz#98b8198b958748a2f322354311023d1d02e7603f"
- integrity sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==
+jest-circus@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-30.3.0.tgz#153614c11ab35867f371bd93496ecb9690b92077"
+ integrity sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==
dependencies:
- "@jest/environment" "30.2.0"
- "@jest/expect" "30.2.0"
- "@jest/test-result" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/environment" "30.3.0"
+ "@jest/expect" "30.3.0"
+ "@jest/test-result" "30.3.0"
+ "@jest/types" "30.3.0"
"@types/node" "*"
chalk "^4.1.2"
co "^4.6.0"
dedent "^1.6.0"
is-generator-fn "^2.1.0"
- jest-each "30.2.0"
- jest-matcher-utils "30.2.0"
- jest-message-util "30.2.0"
- jest-runtime "30.2.0"
- jest-snapshot "30.2.0"
- jest-util "30.2.0"
+ jest-each "30.3.0"
+ jest-matcher-utils "30.3.0"
+ jest-message-util "30.3.0"
+ jest-runtime "30.3.0"
+ jest-snapshot "30.3.0"
+ jest-util "30.3.0"
p-limit "^3.1.0"
- pretty-format "30.2.0"
+ pretty-format "30.3.0"
pure-rand "^7.0.0"
slash "^3.0.0"
stack-utils "^2.0.6"
-jest-cli@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-30.2.0.tgz#1780f8e9d66bf84a10b369aea60aeda7697dcc67"
- integrity sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==
+jest-cli@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-30.3.0.tgz#5ed75a337f486a1f1c5acbb2de8acddb106ead6c"
+ integrity sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==
dependencies:
- "@jest/core" "30.2.0"
- "@jest/test-result" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/core" "30.3.0"
+ "@jest/test-result" "30.3.0"
+ "@jest/types" "30.3.0"
chalk "^4.1.2"
exit-x "^0.2.2"
import-local "^3.2.0"
- jest-config "30.2.0"
- jest-util "30.2.0"
- jest-validate "30.2.0"
+ jest-config "30.3.0"
+ jest-util "30.3.0"
+ jest-validate "30.3.0"
yargs "^17.7.2"
-jest-config@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-30.2.0.tgz#29df8c50e2ad801cc59c406b50176c18c362a90b"
- integrity sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==
+jest-config@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-30.3.0.tgz#b969e0aaaf5964419e62953bb712c16d15972425"
+ integrity sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==
dependencies:
"@babel/core" "^7.27.4"
"@jest/get-type" "30.1.0"
"@jest/pattern" "30.0.1"
- "@jest/test-sequencer" "30.2.0"
- "@jest/types" "30.2.0"
- babel-jest "30.2.0"
+ "@jest/test-sequencer" "30.3.0"
+ "@jest/types" "30.3.0"
+ babel-jest "30.3.0"
chalk "^4.1.2"
ci-info "^4.2.0"
deepmerge "^4.3.1"
- glob "^10.3.10"
+ glob "^10.5.0"
graceful-fs "^4.2.11"
- jest-circus "30.2.0"
+ jest-circus "30.3.0"
jest-docblock "30.2.0"
- jest-environment-node "30.2.0"
+ jest-environment-node "30.3.0"
jest-regex-util "30.0.1"
- jest-resolve "30.2.0"
- jest-runner "30.2.0"
- jest-util "30.2.0"
- jest-validate "30.2.0"
- micromatch "^4.0.8"
+ jest-resolve "30.3.0"
+ jest-runner "30.3.0"
+ jest-util "30.3.0"
+ jest-validate "30.3.0"
parse-json "^5.2.0"
- pretty-format "30.2.0"
+ pretty-format "30.3.0"
slash "^3.0.0"
strip-json-comments "^3.1.1"
-jest-diff@30.2.0, jest-diff@^30.0.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-30.2.0.tgz#e3ec3a6ea5c5747f605c9e874f83d756cba36825"
- integrity sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==
+jest-diff@30.3.0, jest-diff@^30.0.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-30.3.0.tgz#e0a4c84ef350ffd790ffd5b0016acabeecf5f759"
+ integrity sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==
dependencies:
- "@jest/diff-sequences" "30.0.1"
+ "@jest/diff-sequences" "30.3.0"
"@jest/get-type" "30.1.0"
chalk "^4.1.2"
- pretty-format "30.2.0"
+ pretty-format "30.3.0"
jest-docblock@30.2.0:
version "30.2.0"
@@ -6531,40 +6450,38 @@ jest-docblock@30.2.0:
dependencies:
detect-newline "^3.1.0"
-jest-each@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-30.2.0.tgz#39e623ae71641c2ac3ee69b3ba3d258fce8e768d"
- integrity sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==
+jest-each@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-30.3.0.tgz#faa7229bf7a9fa6426dc604057a7d2a173493b1e"
+ integrity sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==
dependencies:
"@jest/get-type" "30.1.0"
- "@jest/types" "30.2.0"
+ "@jest/types" "30.3.0"
chalk "^4.1.2"
- jest-util "30.2.0"
- pretty-format "30.2.0"
+ jest-util "30.3.0"
+ pretty-format "30.3.0"
-jest-environment-jsdom@^30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-30.2.0.tgz#e95e0921ed22be974f1d8a324766d12b1844cb2c"
- integrity sha512-zbBTiqr2Vl78pKp/laGBREYzbZx9ZtqPjOK4++lL4BNDhxRnahg51HtoDrk9/VjIy9IthNEWdKVd7H5bqBhiWQ==
+jest-environment-jsdom@^30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-30.3.0.tgz#6bf80519643333ae2faa07b5660d80451d328578"
+ integrity sha512-RLEOJy6ip1lpw0yqJ8tB3i88FC7VBz7i00Zvl2qF71IdxjS98gC9/0SPWYIBVXHm5hgCYK0PAlSlnHGGy9RoMg==
dependencies:
- "@jest/environment" "30.2.0"
- "@jest/environment-jsdom-abstract" "30.2.0"
- "@types/jsdom" "^21.1.7"
- "@types/node" "*"
+ "@jest/environment" "30.3.0"
+ "@jest/environment-jsdom-abstract" "30.3.0"
jsdom "^26.1.0"
-jest-environment-node@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-30.2.0.tgz#3def7980ebd2fd86e74efd4d2e681f55ab38da0f"
- integrity sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==
+jest-environment-node@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-30.3.0.tgz#aa8a57c5d0c4af0f8b1f7403ba737fec6b3aabbe"
+ integrity sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==
dependencies:
- "@jest/environment" "30.2.0"
- "@jest/fake-timers" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/environment" "30.3.0"
+ "@jest/fake-timers" "30.3.0"
+ "@jest/types" "30.3.0"
"@types/node" "*"
- jest-mock "30.2.0"
- jest-util "30.2.0"
- jest-validate "30.2.0"
+ jest-mock "30.3.0"
+ jest-util "30.3.0"
+ jest-validate "30.3.0"
jest-extended@^7.0.0:
version "7.0.0"
@@ -6573,65 +6490,65 @@ jest-extended@^7.0.0:
dependencies:
jest-diff "^30.0.0"
-jest-haste-map@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-30.2.0.tgz#808e3889f288603ac70ff0ac047598345a66022e"
- integrity sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==
+jest-haste-map@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-30.3.0.tgz#1ea6843e6e45c077d91270666a4fcba958c24cd5"
+ integrity sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==
dependencies:
- "@jest/types" "30.2.0"
+ "@jest/types" "30.3.0"
"@types/node" "*"
anymatch "^3.1.3"
fb-watchman "^2.0.2"
graceful-fs "^4.2.11"
jest-regex-util "30.0.1"
- jest-util "30.2.0"
- jest-worker "30.2.0"
- micromatch "^4.0.8"
+ jest-util "30.3.0"
+ jest-worker "30.3.0"
+ picomatch "^4.0.3"
walker "^1.0.8"
optionalDependencies:
fsevents "^2.3.3"
-jest-leak-detector@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz#292fdca7b7c9cf594e1e570ace140b01d8beb736"
- integrity sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==
+jest-leak-detector@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz#a695a851e353f517a554a2f5c91c2742fc131c98"
+ integrity sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==
dependencies:
"@jest/get-type" "30.1.0"
- pretty-format "30.2.0"
+ pretty-format "30.3.0"
-jest-matcher-utils@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz#69a0d4c271066559ec8b0d8174829adc3f23a783"
- integrity sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==
+jest-matcher-utils@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz#d6c739fec1ecd33809f2d2b1348f6ab01d2f2493"
+ integrity sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==
dependencies:
"@jest/get-type" "30.1.0"
chalk "^4.1.2"
- jest-diff "30.2.0"
- pretty-format "30.2.0"
+ jest-diff "30.3.0"
+ pretty-format "30.3.0"
-jest-message-util@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-30.2.0.tgz#fc97bf90d11f118b31e6131e2b67fc4f39f92152"
- integrity sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==
+jest-message-util@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-30.3.0.tgz#4d723544d36890ba862ac3961db52db5b0d1ba39"
+ integrity sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==
dependencies:
"@babel/code-frame" "^7.27.1"
- "@jest/types" "30.2.0"
+ "@jest/types" "30.3.0"
"@types/stack-utils" "^2.0.3"
chalk "^4.1.2"
graceful-fs "^4.2.11"
- micromatch "^4.0.8"
- pretty-format "30.2.0"
+ picomatch "^4.0.3"
+ pretty-format "30.3.0"
slash "^3.0.0"
stack-utils "^2.0.6"
-jest-mock@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-30.2.0.tgz#69f991614eeb4060189459d3584f710845bff45e"
- integrity sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==
+jest-mock@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-30.3.0.tgz#e0fa4184a596a6c4fdec53d4f412158418923747"
+ integrity sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==
dependencies:
- "@jest/types" "30.2.0"
+ "@jest/types" "30.3.0"
"@types/node" "*"
- jest-util "30.2.0"
+ jest-util "30.3.0"
jest-pnp-resolver@^1.2.3:
version "1.2.3"
@@ -6643,169 +6560,169 @@ jest-regex-util@30.0.1:
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-30.0.1.tgz#f17c1de3958b67dfe485354f5a10093298f2a49b"
integrity sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==
-jest-resolve-dependencies@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz#3370e2c0b49cc560f6a7e8ec3a59dd99525e1a55"
- integrity sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==
+jest-resolve-dependencies@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz#4d638c9f0d93a62a6ed25dec874bfd7e756c8ce5"
+ integrity sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==
dependencies:
jest-regex-util "30.0.1"
- jest-snapshot "30.2.0"
+ jest-snapshot "30.3.0"
-jest-resolve@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-30.2.0.tgz#2e2009cbd61e8f1f003355d5ec87225412cebcd7"
- integrity sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==
+jest-resolve@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-30.3.0.tgz#b7bee9927279805b1b50715d2170a545553b87ff"
+ integrity sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==
dependencies:
chalk "^4.1.2"
graceful-fs "^4.2.11"
- jest-haste-map "30.2.0"
+ jest-haste-map "30.3.0"
jest-pnp-resolver "^1.2.3"
- jest-util "30.2.0"
- jest-validate "30.2.0"
+ jest-util "30.3.0"
+ jest-validate "30.3.0"
slash "^3.0.0"
unrs-resolver "^1.7.11"
-jest-runner@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-30.2.0.tgz#c62b4c3130afa661789705e13a07bdbcec26a114"
- integrity sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==
- dependencies:
- "@jest/console" "30.2.0"
- "@jest/environment" "30.2.0"
- "@jest/test-result" "30.2.0"
- "@jest/transform" "30.2.0"
- "@jest/types" "30.2.0"
+jest-runner@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-30.3.0.tgz#fa970fc4e45d418ad7e7d581b24cac7af5944cb7"
+ integrity sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==
+ dependencies:
+ "@jest/console" "30.3.0"
+ "@jest/environment" "30.3.0"
+ "@jest/test-result" "30.3.0"
+ "@jest/transform" "30.3.0"
+ "@jest/types" "30.3.0"
"@types/node" "*"
chalk "^4.1.2"
emittery "^0.13.1"
exit-x "^0.2.2"
graceful-fs "^4.2.11"
jest-docblock "30.2.0"
- jest-environment-node "30.2.0"
- jest-haste-map "30.2.0"
- jest-leak-detector "30.2.0"
- jest-message-util "30.2.0"
- jest-resolve "30.2.0"
- jest-runtime "30.2.0"
- jest-util "30.2.0"
- jest-watcher "30.2.0"
- jest-worker "30.2.0"
+ jest-environment-node "30.3.0"
+ jest-haste-map "30.3.0"
+ jest-leak-detector "30.3.0"
+ jest-message-util "30.3.0"
+ jest-resolve "30.3.0"
+ jest-runtime "30.3.0"
+ jest-util "30.3.0"
+ jest-watcher "30.3.0"
+ jest-worker "30.3.0"
p-limit "^3.1.0"
source-map-support "0.5.13"
-jest-runtime@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-30.2.0.tgz#395ea792cde048db1b0cd1a92dc9cb9f1921bf8a"
- integrity sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==
+jest-runtime@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-30.3.0.tgz#1a9bec7a9b68db12dfe4136bbe41ab883ea2c996"
+ integrity sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==
dependencies:
- "@jest/environment" "30.2.0"
- "@jest/fake-timers" "30.2.0"
- "@jest/globals" "30.2.0"
+ "@jest/environment" "30.3.0"
+ "@jest/fake-timers" "30.3.0"
+ "@jest/globals" "30.3.0"
"@jest/source-map" "30.0.1"
- "@jest/test-result" "30.2.0"
- "@jest/transform" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/test-result" "30.3.0"
+ "@jest/transform" "30.3.0"
+ "@jest/types" "30.3.0"
"@types/node" "*"
chalk "^4.1.2"
cjs-module-lexer "^2.1.0"
collect-v8-coverage "^1.0.2"
- glob "^10.3.10"
+ glob "^10.5.0"
graceful-fs "^4.2.11"
- jest-haste-map "30.2.0"
- jest-message-util "30.2.0"
- jest-mock "30.2.0"
+ jest-haste-map "30.3.0"
+ jest-message-util "30.3.0"
+ jest-mock "30.3.0"
jest-regex-util "30.0.1"
- jest-resolve "30.2.0"
- jest-snapshot "30.2.0"
- jest-util "30.2.0"
+ jest-resolve "30.3.0"
+ jest-snapshot "30.3.0"
+ jest-util "30.3.0"
slash "^3.0.0"
strip-bom "^4.0.0"
-jest-snapshot@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-30.2.0.tgz#266fbbb4b95fc4665ce6f32f1f38eeb39f4e26d0"
- integrity sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==
+jest-snapshot@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-30.3.0.tgz#6e7ea75069dda86e36311a0f73189e830d4f51ad"
+ integrity sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==
dependencies:
"@babel/core" "^7.27.4"
"@babel/generator" "^7.27.5"
"@babel/plugin-syntax-jsx" "^7.27.1"
"@babel/plugin-syntax-typescript" "^7.27.1"
"@babel/types" "^7.27.3"
- "@jest/expect-utils" "30.2.0"
+ "@jest/expect-utils" "30.3.0"
"@jest/get-type" "30.1.0"
- "@jest/snapshot-utils" "30.2.0"
- "@jest/transform" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/snapshot-utils" "30.3.0"
+ "@jest/transform" "30.3.0"
+ "@jest/types" "30.3.0"
babel-preset-current-node-syntax "^1.2.0"
chalk "^4.1.2"
- expect "30.2.0"
+ expect "30.3.0"
graceful-fs "^4.2.11"
- jest-diff "30.2.0"
- jest-matcher-utils "30.2.0"
- jest-message-util "30.2.0"
- jest-util "30.2.0"
- pretty-format "30.2.0"
+ jest-diff "30.3.0"
+ jest-matcher-utils "30.3.0"
+ jest-message-util "30.3.0"
+ jest-util "30.3.0"
+ pretty-format "30.3.0"
semver "^7.7.2"
synckit "^0.11.8"
-jest-util@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-30.2.0.tgz#5142adbcad6f4e53c2776c067a4db3c14f913705"
- integrity sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==
+jest-util@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-30.3.0.tgz#95a4fbacf2dac20e768e2f1744b70519f2ba7980"
+ integrity sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==
dependencies:
- "@jest/types" "30.2.0"
+ "@jest/types" "30.3.0"
"@types/node" "*"
chalk "^4.1.2"
ci-info "^4.2.0"
graceful-fs "^4.2.11"
- picomatch "^4.0.2"
+ picomatch "^4.0.3"
-jest-validate@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-30.2.0.tgz#273eaaed4c0963b934b5b31e96289edda6e0a2ef"
- integrity sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==
+jest-validate@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-30.3.0.tgz#215e11b8fcc5e2ca4b99ea5d730a5b4c969e4355"
+ integrity sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==
dependencies:
"@jest/get-type" "30.1.0"
- "@jest/types" "30.2.0"
+ "@jest/types" "30.3.0"
camelcase "^6.3.0"
chalk "^4.1.2"
leven "^3.1.0"
- pretty-format "30.2.0"
+ pretty-format "30.3.0"
-jest-watcher@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-30.2.0.tgz#f9c055de48e18c979e7756a3917e596e2d69b07b"
- integrity sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==
+jest-watcher@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-30.3.0.tgz#3afa1af355b9fe80f0261eb8a23981a315858596"
+ integrity sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==
dependencies:
- "@jest/test-result" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/test-result" "30.3.0"
+ "@jest/types" "30.3.0"
"@types/node" "*"
ansi-escapes "^4.3.2"
chalk "^4.1.2"
emittery "^0.13.1"
- jest-util "30.2.0"
+ jest-util "30.3.0"
string-length "^4.0.2"
-jest-worker@30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-30.2.0.tgz#fd5c2a36ff6058ec8f74366ec89538cc99539d26"
- integrity sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==
+jest-worker@30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-30.3.0.tgz#ae4dc1f1d93d0cba1415624fcedaec40ea764f14"
+ integrity sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==
dependencies:
"@types/node" "*"
"@ungap/structured-clone" "^1.3.0"
- jest-util "30.2.0"
+ jest-util "30.3.0"
merge-stream "^2.0.0"
supports-color "^8.1.1"
-jest@^30.2.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/jest/-/jest-30.2.0.tgz#9f0a71e734af968f26952b5ae4b724af82681630"
- integrity sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==
+jest@^30.3.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/jest/-/jest-30.3.0.tgz#6460b889dd805e9677400505f16f1d9b14c285a3"
+ integrity sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==
dependencies:
- "@jest/core" "30.2.0"
- "@jest/types" "30.2.0"
+ "@jest/core" "30.3.0"
+ "@jest/types" "30.3.0"
import-local "^3.2.0"
- jest-cli "30.2.0"
+ jest-cli "30.3.0"
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
@@ -7006,11 +6923,6 @@ kleur@^4.0.3:
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.4.tgz#8c202987d7e577766d039a8cd461934c01cda04d"
integrity sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==
-known-css-properties@^0.37.0:
- version "0.37.0"
- resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.37.0.tgz#10ebe49b9dbb6638860ff8a002fb65a053f4aec5"
- integrity sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==
-
koa-bodyparser@^4.4.1:
version "4.4.1"
resolved "https://registry.yarnpkg.com/koa-bodyparser/-/koa-bodyparser-4.4.1.tgz#a908d848e142cc57d9eece478e932bf00dce3029"
@@ -7323,9 +7235,9 @@ lodash.truncate@^4.4.2:
integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==
lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21:
- version "4.17.23"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.23.tgz#f113b0378386103be4f6893388c73d0bde7f2c5a"
- integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==
+ version "4.18.1"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.18.1.tgz#ff2b66c1f6326d59513de2407bf881439812771c"
+ integrity sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==
log-symbols@^4.1.0:
version "4.1.0"
@@ -7754,10 +7666,10 @@ mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0:
resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz#56c506d065fbf769515235e577b5a261552d56e9"
integrity sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==
-mdn-data@2.12.2:
- version "2.12.2"
- resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.12.2.tgz#9ae6c41a9e65adf61318b32bff7b64fbfb13f8cf"
- integrity sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==
+mdn-data@2.27.1:
+ version "2.27.1"
+ resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.27.1.tgz#e37b9c50880b75366c4d40ac63d9bbcacdb61f0e"
+ integrity sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==
media-typer@0.3.0:
version "0.3.0"
@@ -7809,10 +7721,10 @@ meow@^13.0.0:
resolved "https://registry.yarnpkg.com/meow/-/meow-13.2.0.tgz#6b7d63f913f984063b3cc261b6e8800c4cd3474f"
integrity sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==
-meow@^14.0.0:
- version "14.0.0"
- resolved "https://registry.yarnpkg.com/meow/-/meow-14.0.0.tgz#97d44d2f9eeb9836db06108570891f7523103bbc"
- integrity sha512-JhC3R1f6dbspVtmF3vKjAWz1EVIvwFrGGPLSdU6rK79xBwHWTuHoLnRX/t1/zHS1Ch1Y2UtIrih7DAHuH9JFJA==
+meow@^14.1.0:
+ version "14.1.0"
+ resolved "https://registry.yarnpkg.com/meow/-/meow-14.1.0.tgz#3cd2d16ad534829ab12fcb5010fc2fdb89facd31"
+ integrity sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw==
meow@^7.1.0:
version "7.1.1"
@@ -8286,7 +8198,7 @@ minimatch@^8.0.2:
dependencies:
brace-expansion "^2.0.1"
-minimatch@^9.0.4, minimatch@^9.0.5:
+minimatch@^9.0.4:
version "9.0.5"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
@@ -8447,10 +8359,10 @@ node-int64@^0.4.0:
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
-node-releases@^2.0.27:
- version "2.0.27"
- resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e"
- integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==
+node-releases@^2.0.36:
+ version "2.0.37"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.37.tgz#9bd4f10b77ba39c2b9402d4e8399c482a797f671"
+ integrity sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==
nopt@^2.2.0:
version "2.2.1"
@@ -9089,10 +9001,10 @@ postcss-value-parser@^4.2.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
-postcss@^8.4.32, postcss@^8.5.6, postcss@^8.5.8:
- version "8.5.8"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.8.tgz#6230ecc8fb02e7a0f6982e53990937857e13f399"
- integrity sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==
+postcss@^8.4.32, postcss@^8.5.10, postcss@^8.5.8:
+ version "8.5.10"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.10.tgz#8992d8c30acf3f12169e7c09514a12fed7e48356"
+ integrity sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==
dependencies:
nanoid "^3.3.11"
picocolors "^1.1.1"
@@ -9113,20 +9025,20 @@ prelude-ls@^1.2.1:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
-prettier@^3.8.1:
- version "3.8.1"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.8.1.tgz#edf48977cf991558f4fcbd8a3ba6015ba2a3a173"
- integrity sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==
+prettier@^3.8.3:
+ version "3.8.3"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.8.3.tgz#560f2de55bf01b4c0503bc629d5df99b9a1d09b0"
+ integrity sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==
pretty-bytes@^5.3.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==
-pretty-format@30.2.0, pretty-format@^30.0.0:
- version "30.2.0"
- resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-30.2.0.tgz#2d44fe6134529aed18506f6d11509d8a62775ebe"
- integrity sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==
+pretty-format@30.3.0, pretty-format@^30.0.0:
+ version "30.3.0"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-30.3.0.tgz#e977eed4bcd1b6195faed418af8eac68b9ea1f29"
+ integrity sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==
dependencies:
"@jest/schemas" "30.0.5"
ansi-styles "^5.2.0"
@@ -9175,10 +9087,10 @@ proto-list@~1.2.1:
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==
-protobufjs@^8.0.0:
- version "8.0.0"
- resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-8.0.0.tgz#d884102c1fe8d0b1e2493789ad37bc7ea47c0893"
- integrity sha512-jx6+sE9h/UryaCZhsJWbJtTEy47yXoGNYI4z8ZaRncM0zBKeRqjO2JEcOUYwrYGb1WLhXM1FfMzW3annvFv0rw==
+protobufjs@^8.0.1:
+ version "8.0.1"
+ resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-8.0.1.tgz#c1781abf9a73812cbd483b32138ac59948223806"
+ integrity sha512-NWWCCscLjs+cOKF/s/XVNFRW7Yih0fdH+9brffR5NZCy8k42yRdl5KlWKMVXuI1vfCoy4o1z80XR/W/QUb3V3w==
dependencies:
"@protobufjs/aspromise" "^1.1.2"
"@protobufjs/base64" "^1.1.2"
@@ -9368,16 +9280,6 @@ react-splitter-layout@^4.0.0:
resolved "https://registry.yarnpkg.com/react-splitter-layout/-/react-splitter-layout-4.0.0.tgz#70b43ca6a78c056f5e5fbf29c67b597f040fbf2e"
integrity sha512-SLqOjBOxRuizWUa83w6q5/u9cDWa9/yj9Iko9V9JFN8x+cqIXiDlUFWSx+icz3IIgvsN/oRIw3za5/32RjIwrA==
-react-transition-group@^4.4.5:
- version "4.4.5"
- resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
- integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
- dependencies:
- "@babel/runtime" "^7.5.5"
- dom-helpers "^5.0.1"
- loose-envify "^1.4.0"
- prop-types "^15.6.2"
-
react@^16.8.6:
version "16.14.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"
@@ -10190,7 +10092,7 @@ smob@^1.0.0:
resolved "https://registry.yarnpkg.com/smob/-/smob-1.5.0.tgz#85d79a1403abf128d24d3ebc1cdc5e1a9548d3ab"
integrity sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==
-source-map-js@^1.0.1, source-map-js@^1.2.1:
+source-map-js@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
@@ -10364,16 +10266,7 @@ string-length@^4.0.2:
char-regex "^1.0.2"
strip-ansi "^6.0.0"
-"string-width-cjs@npm:string-width@^4.2.0":
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
-string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -10400,7 +10293,7 @@ string-width@^7.0.0, string-width@^7.2.0:
get-east-asian-width "^1.0.0"
strip-ansi "^7.1.0"
-string-width@^8.1.1:
+string-width@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-8.2.0.tgz#bdb6a9bd6d7800db635adae96cdb0443fec56c42"
integrity sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==
@@ -10503,7 +10396,7 @@ stringify-object@^3.3.0:
is-obj "^1.0.1"
is-regexp "^1.0.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -10517,13 +10410,6 @@ strip-ansi@^0.3.0:
dependencies:
ansi-regex "^0.2.1"
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
strip-ansi@^7.0.1, strip-ansi@^7.1.0, strip-ansi@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.2.tgz#132875abde678c7ea8d691533f2e7e22bb744dba"
@@ -10619,50 +10505,47 @@ stylelint-order@^6.0.2:
postcss "^8.4.32"
postcss-sorting "^8.0.2"
-stylelint@^17.3.0:
- version "17.3.0"
- resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-17.3.0.tgz#18fa199862205516d7011524557fae4ff5b9d60f"
- integrity sha512-1POV91lcEMhj6SLVaOeA0KlS9yattS+qq+cyWqP/nYzWco7K5jznpGH1ExngvPlTM9QF1Kjd2bmuzJu9TH2OcA==
+stylelint@^17.6.0:
+ version "17.6.0"
+ resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-17.6.0.tgz#029731f853f407699ef49713b1a7b550cc458012"
+ integrity sha512-tokrsMIVAR9vAQ/q3UVEr7S0dGXCi7zkCezPRnS2kqPUulvUh5Vgfwngrk4EoAoW7wnrThqTdnTFN5Ra7CaxIg==
dependencies:
"@csstools/css-calc" "^3.1.1"
"@csstools/css-parser-algorithms" "^4.0.0"
- "@csstools/css-syntax-patches-for-csstree" "^1.0.26"
+ "@csstools/css-syntax-patches-for-csstree" "^1.1.1"
"@csstools/css-tokenizer" "^4.0.0"
"@csstools/media-query-list-parser" "^5.0.0"
"@csstools/selector-resolve-nested" "^4.0.0"
"@csstools/selector-specificity" "^6.0.0"
- balanced-match "^3.0.1"
colord "^2.9.3"
- cosmiconfig "^9.0.0"
- css-functions-list "^3.2.3"
- css-tree "^3.1.0"
+ cosmiconfig "^9.0.1"
+ css-functions-list "^3.3.3"
+ css-tree "^3.2.1"
debug "^4.4.3"
fast-glob "^3.3.3"
fastest-levenshtein "^1.0.16"
file-entry-cache "^11.1.2"
global-modules "^2.0.0"
- globby "^16.1.0"
+ globby "^16.1.1"
globjoin "^0.1.4"
html-tags "^5.1.0"
ignore "^7.0.5"
import-meta-resolve "^4.2.0"
- imurmurhash "^0.1.4"
is-plain-object "^5.0.0"
- known-css-properties "^0.37.0"
mathml-tag-names "^4.0.0"
- meow "^14.0.0"
+ meow "^14.1.0"
micromatch "^4.0.8"
normalize-path "^3.0.0"
picocolors "^1.1.1"
- postcss "^8.5.6"
+ postcss "^8.5.8"
postcss-safe-parser "^7.0.1"
postcss-selector-parser "^7.1.1"
postcss-value-parser "^4.2.0"
- string-width "^8.1.1"
+ string-width "^8.2.0"
supports-hyperlinks "^4.4.0"
svg-tags "^1.0.0"
table "^6.9.0"
- write-file-atomic "^7.0.0"
+ write-file-atomic "^7.0.1"
supports-color@^0.2.0:
version "0.2.0"
@@ -10923,10 +10806,10 @@ trough@^2.0.0:
resolved "https://registry.yarnpkg.com/trough/-/trough-2.0.2.tgz#94a3aa9d5ce379fc561f6244905b3f36b7458d96"
integrity sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==
-ts-api-utils@^2.4.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.4.0.tgz#2690579f96d2790253bdcf1ca35d569ad78f9ad8"
- integrity sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==
+ts-api-utils@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.5.0.tgz#4acd4a155e22734990a5ed1fe9e97f113bcb37c1"
+ integrity sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==
tsconfig-paths@^3.15.0:
version "3.15.0"
@@ -11080,15 +10963,15 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
-typescript-eslint@^8.56.0:
- version "8.56.0"
- resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.56.0.tgz#f4686ccaaf2fb86daf0133820da40ca5961a2236"
- integrity sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==
+typescript-eslint@^8.59.0:
+ version "8.59.0"
+ resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.59.0.tgz#d1cc7c63559ce7116aeb66d35ec9dbe0063379fd"
+ integrity sha512-BU3ONW9X+v90EcCH9ZS6LMackcVtxRLlI3XrYyqZIwVSHIk7Qf7bFw1z0M9Q0IUxhTMZCf8piY9hTYaNEIASrw==
dependencies:
- "@typescript-eslint/eslint-plugin" "8.56.0"
- "@typescript-eslint/parser" "8.56.0"
- "@typescript-eslint/typescript-estree" "8.56.0"
- "@typescript-eslint/utils" "8.56.0"
+ "@typescript-eslint/eslint-plugin" "8.59.0"
+ "@typescript-eslint/parser" "8.59.0"
+ "@typescript-eslint/typescript-estree" "8.59.0"
+ "@typescript-eslint/utils" "8.59.0"
typescript@^6.0.2:
version "6.0.2"
@@ -11355,7 +11238,7 @@ upath@^1.2.0:
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
-update-browserslist-db@^1.2.0:
+update-browserslist-db@^1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d"
integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==
@@ -11449,10 +11332,10 @@ v8-to-istanbul@^9.0.1:
"@types/istanbul-lib-coverage" "^2.0.1"
convert-source-map "^1.6.0"
-valibot@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/valibot/-/valibot-1.2.0.tgz#8fc720d9e4082ba16e30a914064a39619b2f1d6f"
- integrity sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==
+valibot@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/valibot/-/valibot-1.3.1.tgz#483c5e229b75c0cb441dfaa9392ffe0a1ec53f2f"
+ integrity sha512-sfdRir/QFM0JaF22hqTroPc5xy4DimuGQVKFrzF1YfGwaS1nJot3Y8VqMdLO2Lg27fMzat2yD3pY5PbAYO39Gg==
validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4:
version "3.0.4"
@@ -11900,16 +11783,7 @@ workbox-window@7.4.0, workbox-window@^7.4.0:
"@types/trusted-types" "^2.0.2"
workbox-core "7.4.0"
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
-wrap-ansi@^7.0.0:
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -11959,12 +11833,11 @@ write-file-atomic@^5.0.1:
imurmurhash "^0.1.4"
signal-exit "^4.0.1"
-write-file-atomic@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-7.0.0.tgz#f89def4f223e9bf8b06cc6fdb12bda3a917505c7"
- integrity sha512-YnlPC6JqnZl6aO4uRc+dx5PHguiR9S6WeoLtpxNT9wIG+BDya7ZNE1q7KOjVgaA73hKhKLpVPgJ5QA9THQ5BRg==
+write-file-atomic@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-7.0.1.tgz#0e2a450ab5aa306bcfcd3aed61833b10cc4fb885"
+ integrity sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==
dependencies:
- imurmurhash "^0.1.4"
signal-exit "^4.0.1"
ws@^8.18.0: