From 1ee7b486eb833cf377bb82bd55453d4f297df449 Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Sun, 5 Apr 2026 16:23:11 +0200 Subject: [PATCH 01/16] Remove API functions for seekItem as it's unclean and unused Signed-off-by: Axel Boberg --- CHANGELOG.md | 1 - api/items.js | 20 ---------- docs/api/README.md | 3 -- lib/api/SItems.js | 38 ------------------ lib/api/SItems.unit.test.js | 80 ------------------------------------- 5 files changed, 142 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0d9eade..b356b059 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,6 @@ ### Added - An AI agent - A `bridge.time.now` api for getting the current server time -- The new API function `bridge.items.seekItem` used to seek an item to a specific point in time - The ability to bypass delay and play an item immediately through the api - A new on end action to force stop - In and out points on trimmable items diff --git a/api/items.js b/api/items.js index a8084d27..3af6511d 100644 --- a/api/items.js +++ b/api/items.js @@ -353,26 +353,6 @@ class Items { } } - /** - * Seek an already-playing item to a position - * without re-emitting item.play - * - * Updates willStartPlayingAt / didStartPlayingAt and - * reschedules items.endItem at the correct remaining time - * - * @param { String } id - * @param { Number } positionMs How far into the item's duration to seek - */ - async seekItem (id, positionMs) { - const item = await this.getItem(id) - - if (!item) { - return - } - - this.#props.Commands.executeCommand('items.seekItem', item, positionMs) - } - /** * Play the item and emit * the 'stop' event diff --git a/docs/api/README.md b/docs/api/README.md index 8f7a0da7..602dc326 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -354,9 +354,6 @@ Play an item and set its state to `playing`. | ------ | ---- | ----------- | | `immediate` | `boolean` | Skip any `delay` set on the item and play it immediately | -### `bridge.items.seekItem(id, positionMs): Promise` -Seek an already-playing item to `positionMs` milliseconds into its duration without re-emitting `item.play` and reschedules the `item.end` event at the correct remaining time. - ### `bridge.items.getEffectiveDuration(item): number` Get the effective playback duration of an item in milliseconds, taking `data.inPoint` and `data.outPoint` into account. diff --git a/lib/api/SItems.js b/lib/api/SItems.js index ffcb64b8..3c5515c1 100644 --- a/lib/api/SItems.js +++ b/lib/api/SItems.js @@ -18,7 +18,6 @@ class SItems extends DIBase { this.props.SCommands.registerAsyncCommand('items.getItem', this.getItem.bind(this)) this.props.SCommands.registerAsyncCommand('items.endItem', this.endItem.bind(this)) this.props.SCommands.registerAsyncCommand('items.playItem', this.playItem.bind(this)) - this.props.SCommands.registerAsyncCommand('items.seekItem', this.seekItem.bind(this)) this.props.SCommands.registerAsyncCommand('items.stopItem', this.stopItem.bind(this)) this.props.SCommands.registerAsyncCommand('items.deleteItems', this.deleteItems.bind(this)) this.props.SCommands.registerAsyncCommand('items.scheduleItem', this.scheduleItem.bind(this)) @@ -70,43 +69,6 @@ class SItems extends DIBase { this.props.SEvents.emit('item.play', item) } - /** - * Seek a playing item to a new position - * without re-emitting item.play - * - * Recalculates willStartPlayingAt / didStartPlayingAt - * and reschedules items.endItem at the remaining duration - * - * @param { Item } item - * @param { number } positionMs How far into the item's duration to seek - */ - seekItem (item, positionMs) { - if (!item?.id) { - throw new ApiError('Invalid item object', 'ERR_API_ITEMS_INVALID_ITEM') - } - - const startedAt = Date.now() - positionMs - const totalDuration = Math.max(getEffectiveDuration(item), 0) - const remainingDuration = Math.max(totalDuration - positionMs, 0) - - this.props.SCommands.executeCommand('scheduler.abort', undefined, `end:${item.id}`) - if (!Number.isNaN(remainingDuration) && remainingDuration > 0) { - this.props.SCommands.executeCommand('scheduler.delay', undefined, `end:${item.id}`, remainingDuration, 'items.endItem', item) - } else { - this.endItem(item) - } - - this.props.SState.applyState({ - items: { - [item.id]: { - state: 'playing', - didStartPlayingAt: startedAt, - willStartPlayingAt: startedAt - } - } - }) - } - /** * Mark the end of an item * and emit the item.end event diff --git a/lib/api/SItems.unit.test.js b/lib/api/SItems.unit.test.js index cf26d852..7454dbb2 100644 --- a/lib/api/SItems.unit.test.js +++ b/lib/api/SItems.unit.test.js @@ -124,83 +124,3 @@ describe('playItem', () => { expect(typeof registeredCommands['items.playItem']).toBe('function') }) }) - -describe('seekItem', () => { - test('throws when item has no id', () => { - const { instance } = makeInstance() - expect(() => instance.seekItem({}, 1000)).toThrow() - expect(() => instance.seekItem(null, 1000)).toThrow() - }) - - test('does not emit item.play', () => { - const { instance, SEvents } = makeInstance() - instance.seekItem({ id: 'abc', data: { duration: 10000 } }, 3000) - - const playEmits = SEvents.emit.mock.calls.filter(([event]) => event === 'item.play') - expect(playEmits).toHaveLength(0) - }) - - test('sets state to playing with timestamps offset by positionMs', () => { - const { instance, SState } = makeInstance() - const positionMs = 3000 - const before = Date.now() - instance.seekItem({ id: 'abc', data: { duration: 10000 } }, positionMs) - const after = Date.now() - - expect(SState.applyState).toHaveBeenCalledWith( - expect.objectContaining({ - items: expect.objectContaining({ - abc: expect.objectContaining({ - state: 'playing', - didStartPlayingAt: expect.any(Number), - willStartPlayingAt: expect.any(Number) - }) - }) - }) - ) - - const applied = SState.applyState.mock.calls[0][0].items.abc - expect(applied.willStartPlayingAt).toBeGreaterThanOrEqual(before - positionMs) - expect(applied.willStartPlayingAt).toBeLessThanOrEqual(after - positionMs) - }) - - test('aborts any existing end scheduler before rescheduling', () => { - const { instance, SCommands } = makeInstance() - instance.seekItem({ id: 'abc', data: { duration: 10000 } }, 3000) - - expect(SCommands.executeCommand).toHaveBeenCalledWith( - 'scheduler.abort', undefined, 'end:abc' - ) - }) - - test('schedules endItem at the remaining duration after seek', () => { - const { instance, SCommands } = makeInstance() - const item = { id: 'abc', data: { duration: 10000 } } - instance.seekItem(item, 3000) - - expect(SCommands.executeCommand).toHaveBeenCalledWith( - 'scheduler.delay', undefined, 'end:abc', 7000, 'items.endItem', item - ) - }) - - test('immediately fires endItem when seek position is at or past the total duration', () => { - const { instance, SEvents } = makeInstance() - const item = { id: 'abc', data: { duration: 5000 } } - instance.seekItem(item, 5000) - - expect(SEvents.emit).toHaveBeenCalledWith('item.end', item) - }) - - test('immediately fires endItem when item has no duration', () => { - const { instance, SEvents } = makeInstance() - const item = { id: 'abc' } - instance.seekItem(item, 0) - - expect(SEvents.emit).toHaveBeenCalledWith('item.end', item) - }) - - test('registers items.seekItem as an async command', () => { - const { registeredCommands } = makeInstance() - expect(typeof registeredCommands['items.seekItem']).toBe('function') - }) -}) From 7ea27f0ce6dd25ac347e79813d69809031f27ac0 Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Sun, 5 Apr 2026 17:15:36 +0200 Subject: [PATCH 02/16] Implement the play history as a simple counter Signed-off-by: Axel Boberg --- lib/api/PlayHistory.js | 77 ++++++++++++++++++++++++++++++++++++++++++ lib/api/SItems.js | 30 ++++++++++++++-- 2 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 lib/api/PlayHistory.js diff --git a/lib/api/PlayHistory.js b/lib/api/PlayHistory.js new file mode 100644 index 00000000..efb45f37 --- /dev/null +++ b/lib/api/PlayHistory.js @@ -0,0 +1,77 @@ +// SPDX-FileCopyrightText: 2026 Axel Boberg +// +// SPDX-License-Identifier: MIT + +/* +The maximum number of consecutive plays each spaced +within LOOP_MAX_SPACING_MS of each other before an +item is considered to be in a loop +*/ +const LOOP_MAX_PLAYS = 100 + +/* +The maximum spacing in milliseconds between two +consecutive plays that will increment the loop counter, +a gap larger than this resets the counter +*/ +const LOOP_MAX_SPACING_MS = 20 + +/* +The default maximum number of item ids to track +before the oldest entry is evicted +*/ +const DEFAULT_MAX_ENTRIES = 1000 + +class PlayHistory { + #entries = new Map() + #maxEntries + + /** + * @param { number } maxEntries The maximum number of item ids to + * track before the oldest is evicted + */ + constructor (maxEntries = DEFAULT_MAX_ENTRIES) { + this.#maxEntries = maxEntries + } + + /** + * Record a play for an item and check + * whether it is in a loop + * + * Returns true if the item is considered + * to be looping, false otherwise + * + * @param { string } id The item id + * @returns { boolean } + */ + record (id) { + const now = Date.now() + const entry = this.#entries.get(id) ?? { lastPlayedAt: 0, count: 0 } + + if (now - entry.lastPlayedAt < LOOP_MAX_SPACING_MS) { + entry.count++ + } else { + entry.count = 1 + } + + entry.lastPlayedAt = now + + if (!this.#entries.has(id) && this.#entries.size >= this.#maxEntries) { + this.#entries.delete(this.#entries.keys().next().value) + } + + this.#entries.set(id, entry) + + return entry.count >= LOOP_MAX_PLAYS + } + + /** + * Remove the history for an item + * @param { string } id The item id + */ + delete (id) { + this.#entries.delete(id) + } +} + +module.exports = PlayHistory diff --git a/lib/api/SItems.js b/lib/api/SItems.js index 3c5515c1..30ef3e66 100644 --- a/lib/api/SItems.js +++ b/lib/api/SItems.js @@ -6,9 +6,14 @@ const DIController = require('../../shared/DIController') const DIBase = require('../../shared/DIBase') const ApiError = require('../error/ApiError') -const { getEffectiveDuration } = require('../../shared/items') +const PlayHistory = require('./PlayHistory') + +const itemHelpers = require('../../shared/items') class SItems extends DIBase { + #playHistory = new PlayHistory() + #stopHistory = new PlayHistory() + constructor (...args) { super(...args) this.#setup() @@ -42,13 +47,22 @@ class SItems extends DIBase { throw new ApiError('Invalid item object', 'ERR_API_ITEMS_INVALID_ITEM') } + if (this.#playHistory.record(item.id)) { + this.props.SMessages.createWarningMessage({ + text: `Detected play loop, Bridge prevented the item with id '${item.id}' from being repeatedly played`, + ttl: 30000, + dismissable: true + }) + return + } + this.props.SCommands.executeCommand('scheduler.abort', undefined, `play:${item.id}`) /* Schedule a call to items.endItem if there's a specified duration so that we can fire the item.end event */ - const endDelay = Math.max(getEffectiveDuration(item), 0) + const endDelay = Math.max(itemHelpers.getEffectiveDuration(item), 0) if (!Number.isNaN(endDelay) && endDelay > 0) { this.props.SCommands.executeCommand('scheduler.delay', undefined, `end:${item.id}`, endDelay, 'items.endItem', item) } else { @@ -118,6 +132,15 @@ class SItems extends DIBase { throw new ApiError('Invalid item object', 'ERR_API_ITEMS_INVALID_ITEM') } + if (this.#stopHistory.record(item.id)) { + this.props.SMessages.createWarningMessage({ + text: `Detected stop loop, Bridge prevented the item with id '${item.id}' from being repeatedly stopped`, + ttl: 30000, + dismissable: true + }) + return + } + this.props.SCommands.executeCommand('scheduler.abort', undefined, `play:${item.id}`) this.props.SCommands.executeCommand('scheduler.abort', undefined, `end:${item.id}`) @@ -172,6 +195,8 @@ class SItems extends DIBase { const patch = {} for (const item of items) { patch[item.id] = { $delete: true } + this.#playHistory.delete(item.id) + this.#stopHistory.delete(item.id) } this.props.SState.applyState({ items: patch @@ -184,6 +209,7 @@ class SItems extends DIBase { DIController.main.register('SItems', SItems, [ 'Workspace', 'SCommands', + 'SMessages', 'SEvents', 'SState' ]) From cc840357dd2b9e66dbc94834881a5f2e375bb866 Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Sun, 5 Apr 2026 17:15:53 +0200 Subject: [PATCH 03/16] Add shim for SMessages Signed-off-by: Axel Boberg --- lib/api/SItems.unit.test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/api/SItems.unit.test.js b/lib/api/SItems.unit.test.js index 7454dbb2..989ce9a2 100644 --- a/lib/api/SItems.unit.test.js +++ b/lib/api/SItems.unit.test.js @@ -26,12 +26,17 @@ function makeInstance () { applyState: jest.fn() } + const SMessages = { + createWarningMessage: jest.fn() + } + const Workspace = { state: { data: { items: {} } } } const instance = DIController.main.instantiate('SItems', { SCommands, + SMessages, SEvents, SState, Workspace From c673d27a6257a555fa63ad30890bcd6693480f05 Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Sun, 5 Apr 2026 17:44:24 +0200 Subject: [PATCH 04/16] Use a circular buffer for play history Signed-off-by: Axel Boberg --- lib/api/PlayHistory.js | 104 +++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 39 deletions(-) diff --git a/lib/api/PlayHistory.js b/lib/api/PlayHistory.js index efb45f37..6eb50c7c 100644 --- a/lib/api/PlayHistory.js +++ b/lib/api/PlayHistory.js @@ -3,74 +3,100 @@ // SPDX-License-Identifier: MIT /* -The maximum number of consecutive plays each spaced -within LOOP_MAX_SPACING_MS of each other before an -item is considered to be in a loop +The default size of the sliding window, i.e. the maximum +number of recent plays to keep in memory. Must be at least +twice the length of the largest expected cycle to detect it. */ -const LOOP_MAX_PLAYS = 100 - -/* -The maximum spacing in milliseconds between two -consecutive plays that will increment the loop counter, -a gap larger than this resets the counter -*/ -const LOOP_MAX_SPACING_MS = 20 - -/* -The default maximum number of item ids to track -before the oldest entry is evicted -*/ -const DEFAULT_MAX_ENTRIES = 1000 +const DEFAULT_WINDOW_SIZE = 500 class PlayHistory { - #entries = new Map() - #maxEntries + #buffer + #windowSize + #head = 0 + #size = 0 + + /** + * @param { number } windowSize The number of recent play events to + * retain for cycle detection + */ + constructor (windowSize = DEFAULT_WINDOW_SIZE) { + this.#windowSize = windowSize + this.#buffer = new Array(windowSize) + } /** - * @param { number } maxEntries The maximum number of item ids to - * track before the oldest is evicted + * Get a buffered entry by logical index, + * where 0 is the oldest and size-1 is the newest + * + * @param { number } index + * @returns { string } */ - constructor (maxEntries = DEFAULT_MAX_ENTRIES) { - this.#maxEntries = maxEntries + #get (index) { + return this.#buffer[(this.#head + index) % this.#windowSize] } /** * Record a play for an item and check * whether it is in a loop * - * Returns true if the item is considered - * to be looping, false otherwise + * Appends the id to a sliding window and checks + * whether the tail of that window forms a repeating + * sequence. Returns true if a cycle is detected, + * false otherwise. * * @param { string } id The item id * @returns { boolean } */ record (id) { - const now = Date.now() - const entry = this.#entries.get(id) ?? { lastPlayedAt: 0, count: 0 } + const writePos = (this.#head + this.#size) % this.#windowSize + this.#buffer[writePos] = id - if (now - entry.lastPlayedAt < LOOP_MAX_SPACING_MS) { - entry.count++ + if (this.#size < this.#windowSize) { + this.#size++ } else { - entry.count = 1 + this.#head = (this.#head + 1) % this.#windowSize } - entry.lastPlayedAt = now - - if (!this.#entries.has(id) && this.#entries.size >= this.#maxEntries) { - this.#entries.delete(this.#entries.keys().next().value) + /* + Check whether the most recent L entries exactly repeat + the L entries before them, for all possible cycle lengths + */ + const maxCycleLength = Math.floor(this.#size / 2) + for (let L = 1; L <= maxCycleLength; L++) { + let match = true + for (let i = 0; i < L; i++) { + if (this.#get(this.#size - 1 - i) !== this.#get(this.#size - 1 - L - i)) { + match = false + break + } + } + if (match) { + return true + } } - this.#entries.set(id, entry) - - return entry.count >= LOOP_MAX_PLAYS + return false } /** - * Remove the history for an item + * Remove all occurrences of an item id from the buffer, + * preserving the relative order of remaining entries + * * @param { string } id The item id */ delete (id) { - this.#entries.delete(id) + const entries = [] + for (let i = 0; i < this.#size; i++) { + const val = this.#get(i) + if (val !== id) { + entries.push(val) + } + } + this.#head = 0 + this.#size = entries.length + for (let i = 0; i < entries.length; i++) { + this.#buffer[i] = entries[i] + } } } From 62bdc5f7dfa1f68100420bd6e5cbff07d0e7255b Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Sun, 5 Apr 2026 18:15:54 +0200 Subject: [PATCH 05/16] Fine tune the ring buffer and add a timing parameter Signed-off-by: Axel Boberg --- lib/api/PlayHistory.js | 94 +++++++++++++++++------ lib/api/PlayHistory.unit.test.js | 125 +++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 24 deletions(-) create mode 100644 lib/api/PlayHistory.unit.test.js diff --git a/lib/api/PlayHistory.js b/lib/api/PlayHistory.js index 6eb50c7c..8e96f365 100644 --- a/lib/api/PlayHistory.js +++ b/lib/api/PlayHistory.js @@ -2,13 +2,37 @@ // // SPDX-License-Identifier: MIT -/* -The default size of the sliding window, i.e. the maximum -number of recent plays to keep in memory. Must be at least -twice the length of the largest expected cycle to detect it. -*/ -const DEFAULT_WINDOW_SIZE = 500 +/** + * The default size of the circular buffer, i.e. the maximum + * number of recent plays to keep in memory + * + * Only patterns up to half this size can be detected as + * it needs to appear at lease twice within the buffer + * + * @type { number } + */ +const DEFAULT_BUFFER_SIZE_ENTRIES_N = 500 +/** + * The maximum number of milliseconds allowed between any two + * consecutive plays within a detected cycle for it to be + * considered a runaway loop. If any single step in the cycle + * took longer than this (e.g. an item waiting out its duration), + * the sequence is considered intentional rather than a loop + * + * @type { number } + */ +const MAX_MS_PER_STEP = 10 + +/** + * @class PlayHistory + * @description Keeps track of played items and + * flags an item as a loop if it occurs + * twice within the circular buffer and + * breaks the timing threshold + * + * @typedef {{ id: string, t: number }} Entry + */ class PlayHistory { #buffer #windowSize @@ -16,10 +40,10 @@ class PlayHistory { #size = 0 /** - * @param { number } windowSize The number of recent play events to - * retain for cycle detection + * @param { number } windowSize The number of recent play events to + * retain for cycle detection */ - constructor (windowSize = DEFAULT_WINDOW_SIZE) { + constructor (windowSize = DEFAULT_BUFFER_SIZE_ENTRIES_N) { this.#windowSize = windowSize this.#buffer = new Array(windowSize) } @@ -29,7 +53,7 @@ class PlayHistory { * where 0 is the oldest and size-1 is the newest * * @param { number } index - * @returns { string } + * @returns { Entry } */ #get (index) { return this.#buffer[(this.#head + index) % this.#windowSize] @@ -39,17 +63,19 @@ class PlayHistory { * Record a play for an item and check * whether it is in a loop * - * Appends the id to a sliding window and checks - * whether the tail of that window forms a repeating - * sequence. Returns true if a cycle is detected, - * false otherwise. + * Appends the id and current timestamp to a sliding window + * and checks whether the tail of that window forms a repeating + * sequence whose total duration is within the loop time budget + * + * Returns true if a loop is detected, false otherwise * - * @param { string } id The item id - * @returns { boolean } + * @param { string } id The item id + * @returns { boolean } True if a loop is detected */ record (id) { + const now = Date.now() const writePos = (this.#head + this.#size) % this.#windowSize - this.#buffer[writePos] = id + this.#buffer[writePos] = { id, t: now } if (this.#size < this.#windowSize) { this.#size++ @@ -59,18 +85,38 @@ class PlayHistory { /* Check whether the most recent L entries exactly repeat - the L entries before them, for all possible cycle lengths + the L entries before them, for all possible cycle lengths, + and that the most recent full cycle completed within the + time budget of L × MAX_MS_PER_ITEM milliseconds */ const maxCycleLength = Math.floor(this.#size / 2) for (let L = 1; L <= maxCycleLength; L++) { let match = true for (let i = 0; i < L; i++) { - if (this.#get(this.#size - 1 - i) !== this.#get(this.#size - 1 - L - i)) { + if (this.#get(this.#size - 1 - i).id !== this.#get(this.#size - 1 - L - i).id) { match = false break } } - if (match) { + if (!match) { + continue + } + + /* + Check that every step within the last cycle + fired within MAX_MS_PER_STEP of the previous play + + A single large gap means an item waited out its duration — intentional, not a loop + */ + let isRunaway = true + for (let i = this.#size - L; i < this.#size; i++) { + const gap = this.#get(i).t - this.#get(i - 1).t + if (gap > MAX_MS_PER_STEP) { + isRunaway = false + break + } + } + if (isRunaway) { return true } } @@ -82,14 +128,14 @@ class PlayHistory { * Remove all occurrences of an item id from the buffer, * preserving the relative order of remaining entries * - * @param { string } id The item id + * @param { string } id The item id */ delete (id) { const entries = [] for (let i = 0; i < this.#size; i++) { - const val = this.#get(i) - if (val !== id) { - entries.push(val) + const entry = this.#get(i) + if (entry.id !== id) { + entries.push(entry) } } this.#head = 0 diff --git a/lib/api/PlayHistory.unit.test.js b/lib/api/PlayHistory.unit.test.js new file mode 100644 index 00000000..00ba8fa7 --- /dev/null +++ b/lib/api/PlayHistory.unit.test.js @@ -0,0 +1,125 @@ +// SPDX-FileCopyrightText: 2026 Axel Boberg +// +// SPDX-License-Identifier: MIT + +const PlayHistory = require('./PlayHistory') + +beforeEach(() => { + jest.useFakeTimers() +}) + +afterEach(() => { + jest.useRealTimers() +}) + +test('does not flag a single play', () => { + const history = new PlayHistory() + expect(history.record('a')).toBe(false) +}) + +test('does not flag a non-repeating sequence', () => { + const history = new PlayHistory() + expect(history.record('a')).toBe(false) + expect(history.record('b')).toBe(false) + expect(history.record('c')).toBe(false) + expect(history.record('d')).toBe(false) +}) + +test('detects a single-item runaway loop', () => { + const history = new PlayHistory() + history.record('a') + expect(history.record('a')).toBe(true) +}) + +test('detects a two-item runaway loop', () => { + const history = new PlayHistory() + history.record('a') + history.record('b') + history.record('a') + expect(history.record('b')).toBe(true) +}) + +test('detects a multi-item runaway loop', () => { + const history = new PlayHistory() + const cycle = ['a', 'b', 'c', 'd', 'e'] + + for (const id of cycle) { + history.record(id) + } + + let detected = false + for (const id of cycle) { + if (history.record(id)) { + detected = true + break + } + } + + expect(detected).toBe(true) +}) + +test('does not flag a single item played slowly', () => { + const history = new PlayHistory() + history.record('a') + jest.advanceTimersByTime(100) + expect(history.record('a')).toBe(false) +}) + +test('does not flag a timed loop where one step has a gap', () => { + /* + Simulates a group + 100ms media item cycle: + group plays → media item plays (gap ~0ms) → item.end fires after 100ms → group plays again + */ + const history = new PlayHistory() + history.record('group') + history.record('media') + jest.advanceTimersByTime(100) + history.record('group') + expect(history.record('media')).toBe(false) +}) + +test('does not flag a sequence that only partially repeats', () => { + const history = new PlayHistory() + history.record('a') + history.record('b') + history.record('c') + history.record('a') + history.record('b') + // a, b, c, a, b — not a full cycle of any length + expect(history.record('d')).toBe(false) +}) + +test('delete() prevents loop detection for the removed item', () => { + const history = new PlayHistory() + history.record('a') + history.record('b') + history.delete('b') + // Buffer is now just ['a']; playing a, b again should not trigger + history.record('a') + expect(history.record('b')).toBe(false) +}) + +test('delete() preserves loop detection for other items', () => { + const history = new PlayHistory() + history.record('a') + history.record('b') + history.delete('b') + // 'a' is now the only entry; playing 'a' again completes a cycle + expect(history.record('a')).toBe(true) +}) + +test('evicts oldest entry when window is full', () => { + const windowSize = 10 + const history = new PlayHistory(windowSize) + + /* + Fill the window with unique ids so it wraps around, + then verify a fresh cycle is still detected + */ + for (let i = 0; i < windowSize; i++) { + history.record(`item-${i}`) + } + + history.record('x') + expect(history.record('x')).toBe(true) +}) From 6eea87522a5cff584c70676b079ef01ee936c346 Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Sun, 5 Apr 2026 18:37:08 +0200 Subject: [PATCH 06/16] Add a setting for disabling loop prevention Signed-off-by: Axel Boberg --- app/components/Preferences/index.jsx | 9 +++++++- .../Preferences/sections/general.json | 21 +++++++++++++++---- app/components/Preferences/style.css | 8 +++++++ lib/api/SItems.js | 8 +++++-- lib/template.json | 5 +++++ 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/app/components/Preferences/index.jsx b/app/components/Preferences/index.jsx index 2cf8bd92..bbd6fbeb 100644 --- a/app/components/Preferences/index.jsx +++ b/app/components/Preferences/index.jsx @@ -41,6 +41,8 @@ const INTERNAL_SETTINGS = [ } ] +const DIVIDER_SETTING_KEY = 'divider' + export function Preferences ({ onClose = () => {} }) { const [, applyShared] = React.useContext(SharedContext) const [, applyLocal] = React.useContext(LocalContext) @@ -154,12 +156,17 @@ export function Preferences ({ onClose = () => {} }) { { (sections[curPath[0]]?.items[curPath[1]]?.items || []) .filter(setting => setting) - .map(setting => { + .map((setting, i) => { + if (setting?.type === DIVIDER_SETTING_KEY) { + return
+ } + /* Compose a key that's somewhat unique but still static in order to prevent unnecessary re-rendering */ const key = `${setting?.title}${setting?.description}${JSON.stringify(setting?.inputs)}` + return ( Date: Sun, 5 Apr 2026 18:37:21 +0200 Subject: [PATCH 07/16] Add a getState shim to the unit tests Signed-off-by: Axel Boberg --- lib/api/SItems.unit.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/api/SItems.unit.test.js b/lib/api/SItems.unit.test.js index 989ce9a2..33179b7d 100644 --- a/lib/api/SItems.unit.test.js +++ b/lib/api/SItems.unit.test.js @@ -23,7 +23,8 @@ function makeInstance () { } const SState = { - applyState: jest.fn() + applyState: jest.fn(), + getState: jest.fn() } const SMessages = { From 7627a3e72022e39fb8f8341d340821068db625b8 Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Sun, 5 Apr 2026 18:40:34 +0200 Subject: [PATCH 08/16] Update changelog Signed-off-by: Axel Boberg --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b356b059..1f31c251 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - In and out points for trimmable items - A quick way to change caspar targets - An API for opening modals +- Loop detection and prevention ### Changed - Make margins in the inspector smaller ### Fixed From 0941cc20186a575d4ec1a32cf47a481c6b2c79eb Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Mon, 6 Apr 2026 17:35:35 +0200 Subject: [PATCH 09/16] Fix an issue preventing nested groups from being stepped into Signed-off-by: Axel Boberg --- CHANGELOG.md | 3 ++- app/views/WorkspaceWidget.jsx | 2 -- plugins/rundown/app/components/RundownGroupItem/index.jsx | 4 ++-- plugins/rundown/app/components/RundownList/index.jsx | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f31c251..b6aba5b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,8 @@ - An issue where variable autocomplete wouldn't sync with the input field horisontal scroll - A bug where there were no guards for placing a group, or timeline, within itself - A memory leak occuring within caspar widgets hooking onto the state -- UI issues with the caspar library widget +- UI issues with the caspar library widget +- An issue preventing nested groups from being 'stepped into' ## 1.0.0-beta.10 ### Added diff --git a/app/views/WorkspaceWidget.jsx b/app/views/WorkspaceWidget.jsx index 624117c3..6e44510d 100644 --- a/app/views/WorkspaceWidget.jsx +++ b/app/views/WorkspaceWidget.jsx @@ -110,8 +110,6 @@ export const WorkspaceWidget = () => { if (!path) { return } - - console.log('Update', buildChildrenUpdate(path, data)) applyShared({ children: buildChildrenUpdate(path, data) }) } diff --git a/plugins/rundown/app/components/RundownGroupItem/index.jsx b/plugins/rundown/app/components/RundownGroupItem/index.jsx index 44537f2e..a3854b7e 100644 --- a/plugins/rundown/app/components/RundownGroupItem/index.jsx +++ b/plugins/rundown/app/components/RundownGroupItem/index.jsx @@ -11,7 +11,7 @@ import { RundownItemProgress } from '../RundownItemProgress' import { RundownList } from '../RundownList' import { Icon } from '../Icon' -export function RundownGroupItem ({ index, item }) { +export function RundownGroupItem ({ index, item, onChangeRundownId }) { const [shared] = React.useContext(SharedContext) const [isDraggedOver, setIsDraggedOver] = React.useState(false) @@ -179,7 +179,7 @@ export function RundownGroupItem ({ index, item }) { onDrop={e => handleDrop(e)} /> ) - : + : }
diff --git a/plugins/rundown/app/components/RundownList/index.jsx b/plugins/rundown/app/components/RundownList/index.jsx index d1895b7f..cb4517b0 100644 --- a/plugins/rundown/app/components/RundownList/index.jsx +++ b/plugins/rundown/app/components/RundownList/index.jsx @@ -470,7 +470,7 @@ export function RundownList ({ contextMenuItems={contextMenuItems} selected={isSelected} > - + ) }) From 3f750571c38837de442ae3128fd1badd419ab32e Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Mon, 6 Apr 2026 19:03:28 +0200 Subject: [PATCH 10/16] Use getPositionFromEvent to fix an issue with misaligned window menus on Windows Signed-off-by: Axel Boberg --- app/components/AppMenu/AppMenuRootItem.jsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/components/AppMenu/AppMenuRootItem.jsx b/app/components/AppMenu/AppMenuRootItem.jsx index 19f581b9..a52a96cf 100644 --- a/app/components/AppMenu/AppMenuRootItem.jsx +++ b/app/components/AppMenu/AppMenuRootItem.jsx @@ -9,15 +9,9 @@ export function AppMenuRootItem ({ label, spec }) { const elRef = React.useRef() async function handleClick (e) { - const bounds = e.target.getBoundingClientRect() - - const x = e.screenX - (e.clientX - bounds.x) - const y = e.screenY - (e.clientY - bounds.y) + bounds.height + MENU_MARGIN_PX - const bridge = await api.load() bridge.ui.contextMenu.open(spec, { - x, - y + ...bridge.ui.contextMenu.getPositionFromEvent(e) }) } From 73438b124901932226d71d6664f706293944bf98 Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Mon, 6 Apr 2026 19:07:04 +0200 Subject: [PATCH 11/16] Update changelog Signed-off-by: Axel Boberg --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6aba5b5..a85f5de7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - A memory leak occuring within caspar widgets hooking onto the state - UI issues with the caspar library widget - An issue preventing nested groups from being 'stepped into' +- An issue where the menus of window buttons became misaligned on Windows ## 1.0.0-beta.10 ### Added From 0c879fe502f5bd9edab0aa7df18afec849b5da2d Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Mon, 6 Apr 2026 19:55:24 +0200 Subject: [PATCH 12/16] Rebuild native addons when building electron for Windows Signed-off-by: Axel Boberg --- package.json | 2 +- scripts/electron-prebuild.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 916bfce1..a824726b 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "electron:prebuild:x64": "node scripts/electron-prebuild x64", "electron:build:mac:arm": "npm run build && npm run electron:prebuild:arm64 && electron-packager . \"Bridge\" --platform=darwin --arch=arm64 --extend-info extra.plist --icon=media/appicon.icns --overwrite --asar.unpack='**/*.{node,dylib}' --ignore=\"webpack.*\\.js\" --ignore=\"docs/*\" --ignore=\"./README.md\" --ignore=\"./Dockerfile\" --ignore=\"./docker-compose.yml\" --out ./bin", "electron:build:mac:intel": "npm run build && npm run electron:prebuild:x64 && electron-packager . \"Bridge\" --platform=darwin --arch=x64 --extend-info extra.plist --icon=media/appicon.icns --overwrite --asar.unpack='**/*.{node,dylib}' --ignore=\"webpack.*\\.js\" --ignore=\"docs/*\" --ignore=\"./README.md\" --ignore=\"./Dockerfile\" --ignore=\"./docker-compose.yml\" --out ./bin", - "electron:build:win": "npm run build && electron-packager . \"Bridge\" --platform=win32 --arch=x64 --extend-info extra.plist --icon=media/appicon.ico --overwrite --asar.unpack='**/*.{node,dylib}' --ignore=\"webpack.*\\.js\" --ignore=\"docs/*\" --ignore=\"./README.md\" --ignore=\"./Dockerfile\" --ignore=\"./docker-compose.yml\" --out ./bin", + "electron:build:win": "npm run build && npm run electron:prebuild:x64 && electron-packager . \"Bridge\" --platform=win32 --arch=x64 --extend-info extra.plist --icon=media/appicon.ico --overwrite --asar.unpack='**/*.{node,dylib}' --ignore=\"webpack.*\\.js\" --ignore=\"docs/*\" --ignore=\"./README.md\" --ignore=\"./Dockerfile\" --ignore=\"./docker-compose.yml\" --out ./bin", "electron:sign:mac": "node scripts/sign-macos.js", "prepare": "husky install", "postinstall": "node scripts/install-plugin-dependencies.js" diff --git a/scripts/electron-prebuild.js b/scripts/electron-prebuild.js index 9ce33945..469f286c 100644 --- a/scripts/electron-prebuild.js +++ b/scripts/electron-prebuild.js @@ -1,7 +1,7 @@ /** * @description - * Pre build actions for macOS-builds - * Run as `node electron-prebuild-macos.js ` + * Pre build actions for Electron builds + * Run as `node electron-prebuild.js ` * * Actions: * - Rebuild native addons for all plugins From 6cf2ce390dcea3f813842851e2c956f36e2d8594 Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Mon, 6 Apr 2026 22:01:55 +0200 Subject: [PATCH 13/16] Update dependencies Signed-off-by: Axel Boberg --- package-lock.json | 92 +++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/package-lock.json b/package-lock.json index e24dedb4..0a46b09f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2266,9 +2266,9 @@ } }, "node_modules/@electron/universal/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -2990,9 +2990,9 @@ } }, "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -4185,9 +4185,9 @@ } }, "node_modules/@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "version": "0.8.12", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.12.tgz", + "integrity": "sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg==", "dev": true, "license": "MIT", "engines": { @@ -4381,9 +4381,9 @@ } }, "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -4928,9 +4928,9 @@ "optional": true }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -5094,9 +5094,9 @@ } }, "node_modules/cacache/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -6216,9 +6216,9 @@ "license": "MIT" }, "node_modules/electron": { - "version": "38.1.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-38.1.0.tgz", - "integrity": "sha512-ypA8GF8RU4HD5pA1sa0/2U8k+92EPP2c7pX+3XbgB760F7OmqrFXtYkOilVw6HfV4+lk88XxqigmsUKTACQYoQ==", + "version": "38.8.6", + "resolved": "https://registry.npmjs.org/electron/-/electron-38.8.6.tgz", + "integrity": "sha512-lyBhcVi9QYAZL6FO6r5twAWAjWnYomo3iVDvrb5SJZlq928BGemHOKG0tPIq41NOLaCu9f3XdEEjMkjQPjprRg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -9289,9 +9289,9 @@ } }, "node_modules/jest-config/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -9700,9 +9700,9 @@ } }, "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -10149,9 +10149,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "dev": true, "license": "MIT" }, @@ -10385,9 +10385,9 @@ } }, "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -10953,16 +10953,16 @@ } }, "node_modules/nodemon/node_modules/brace-expansion": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", - "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" } }, "node_modules/nodemon/node_modules/has-flag": { @@ -11536,9 +11536,9 @@ "license": "ISC" }, "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", + "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", "license": "MIT" }, "node_modules/path-type": { @@ -11584,9 +11584,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -12374,9 +12374,9 @@ } }, "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { From af56d8750b0bf43cf8fea6a204860c4c4ba16807 Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Mon, 6 Apr 2026 22:08:23 +0200 Subject: [PATCH 14/16] Update Electron to 41.1.1 Signed-off-by: Axel Boberg --- package-lock.json | 47 ++++++++++++++++++++++++----------------------- package.json | 4 ++-- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a46b09f..b2363d49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,10 +35,10 @@ "@dotenvx/dotenvx": "^1.38.4", "@electron/osx-sign": "^1.3.2", "@electron/packager": "^18.3.3", - "@electron/rebuild": "^4.0.2", + "@electron/rebuild": "^4.0.3", "babel-loader": "^8.2.2", "css-loader": "^5.2.0", - "electron": "^38.1.0", + "electron": "^41.1.1", "eslint": "^8.38.0", "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.27.5", @@ -3654,13 +3654,13 @@ } }, "node_modules/@types/node": { - "version": "22.18.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.3.tgz", - "integrity": "sha512-gTVM8js2twdtqM+AE2PdGEe9zGQY4UvmFjan9rZcVb6FGdStfjWoWejdmy4CfWVO9rh5MiYQGZloKAGkJt8lMw==", + "version": "24.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz", + "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/responselike": { @@ -5107,6 +5107,7 @@ "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -6216,15 +6217,15 @@ "license": "MIT" }, "node_modules/electron": { - "version": "38.8.6", - "resolved": "https://registry.npmjs.org/electron/-/electron-38.8.6.tgz", - "integrity": "sha512-lyBhcVi9QYAZL6FO6r5twAWAjWnYomo3iVDvrb5SJZlq928BGemHOKG0tPIq41NOLaCu9f3XdEEjMkjQPjprRg==", + "version": "41.1.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-41.1.1.tgz", + "integrity": "sha512-8bgvDhBjli+3Z2YCKgzzoBPh6391pr7Xv2h/tTJG4ETgvPvUxZomObbZLs31mUzYb6VrlcDDd9cyWyNKtPm3tA==", "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { "@electron/get": "^2.0.0", - "@types/node": "^22.7.7", + "@types/node": "^24.9.0", "extract-zip": "^2.0.1" }, "bin": { @@ -10590,11 +10591,11 @@ } }, "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", + "integrity": "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { "minipass": "^3.0.0" }, @@ -10777,9 +10778,9 @@ } }, "node_modules/node-abi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-4.24.0.tgz", - "integrity": "sha512-u2EC1CeNe25uVtX3EZbdQ275c74zdZmmpzrHEQh2aIYqoVjlglfUpOX9YY85x1nlBydEKDVaSmMNhR7N82Qj8A==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-4.28.0.tgz", + "integrity": "sha512-Qfp5XZL1cJDOabOT8H5gnqMTmM4NjvYzHp4I/Kt/Sl76OVkOBBHRFlPspGV0hYvMoqQsypFjT/Yp7Km0beXW9g==", "dev": true, "license": "MIT", "dependencies": { @@ -13684,9 +13685,9 @@ } }, "node_modules/tar": { - "version": "7.5.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.11.tgz", - "integrity": "sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==", + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", + "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -14088,9 +14089,9 @@ "license": "MIT" }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index a824726b..579ea529 100644 --- a/package.json +++ b/package.json @@ -61,10 +61,10 @@ "@dotenvx/dotenvx": "^1.38.4", "@electron/osx-sign": "^1.3.2", "@electron/packager": "^18.3.3", - "@electron/rebuild": "^4.0.2", + "@electron/rebuild": "^4.0.3", "babel-loader": "^8.2.2", "css-loader": "^5.2.0", - "electron": "^38.1.0", + "electron": "^41.1.1", "eslint": "^8.38.0", "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.27.5", From 5fb0ed1e21990f62565456f4d320c69ddc93999a Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Mon, 6 Apr 2026 22:09:01 +0200 Subject: [PATCH 15/16] Update changelog Signed-off-by: Axel Boberg --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a85f5de7..4c2229f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ - UI issues with the caspar library widget - An issue preventing nested groups from being 'stepped into' - An issue where the menus of window buttons became misaligned on Windows +- Updated non-breaking dependencies +- Updated Electron to 41.1.1 ## 1.0.0-beta.10 ### Added From f7d2798e29b0d2fd206592ce93981bdf20161a50 Mon Sep 17 00:00:00 2001 From: Axel Boberg Date: Mon, 6 Apr 2026 22:13:25 +0200 Subject: [PATCH 16/16] Update plugin dependencies Signed-off-by: Axel Boberg --- plugins/agent/package-lock.json | 6 +- plugins/caspar/package-lock.json | 610 ++++++++++++++++------------- plugins/timecode/package-lock.json | 68 ++-- 3 files changed, 369 insertions(+), 315 deletions(-) diff --git a/plugins/agent/package-lock.json b/plugins/agent/package-lock.json index 2321b466..a571f50e 100644 --- a/plugins/agent/package-lock.json +++ b/plugins/agent/package-lock.json @@ -3809,9 +3809,9 @@ "license": "MIT" }, "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", diff --git a/plugins/caspar/package-lock.json b/plugins/caspar/package-lock.json index 28835dc3..b206250c 100644 --- a/plugins/caspar/package-lock.json +++ b/plugins/caspar/package-lock.json @@ -20,18 +20,15 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -39,26 +36,18 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, - "peer": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -66,17 +55,19 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -106,10 +97,11 @@ } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@types/json-schema": { @@ -120,173 +112,189 @@ "peer": true }, "node_modules/@types/node": { - "version": "20.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.8.tgz", - "integrity": "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==", + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz", + "integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~7.18.0" } }, "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, + "license": "Apache-2.0", "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -295,6 +303,7 @@ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", "dev": true, + "license": "BSD-3-Clause", "peer": true }, "node_modules/@xtuc/long": { @@ -302,13 +311,15 @@ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true, + "license": "Apache-2.0", "peer": true }, "node_modules/acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, + "license": "MIT", "peer": true, "bin": { "acorn": "bin/acorn" @@ -317,41 +328,83 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "dev": true, + "license": "MIT", "peer": true, + "engines": { + "node": ">=10.13.0" + }, "peerDependencies": { - "acorn": "^8" + "acorn": "^8.14.0" } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, "peerDependencies": { - "ajv": "^6.9.1" + "ajv": "^8.8.2" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.16", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.16.tgz", + "integrity": "sha512-Lyf3aK28zpsD1yQMiiHD4RvVb6UdMoo8xzG2XzFIfR9luPzOpcBlAsT/qfB1XWS1bxWT+UtE4WmQgsp297FYOA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/big.js": { @@ -364,9 +417,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", "dev": true, "funding": [ { @@ -382,12 +435,14 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "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" }, "bin": { "browserslist": "cli.js" @@ -401,12 +456,13 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/caniuse-lite": { - "version": "1.0.30001636", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", - "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "version": "1.0.30001786", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001786.tgz", + "integrity": "sha512-4oxTZEvqmLLrERwxO76yfKM7acZo310U+v4kqexI2TL1DkkUEMT8UijrxxcnVdxR3qkVf5awGRX+4Z6aPHVKrA==", "dev": true, "funding": [ { @@ -422,6 +478,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "CC-BY-4.0", "peer": true }, "node_modules/chrome-trace-event": { @@ -439,13 +496,15 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/electron-to-chromium": { - "version": "1.4.810", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.810.tgz", - "integrity": "sha512-Kaxhu4T7SJGpRQx99tq216gCq2nMxJo+uuT6uzz9l8TVN2stL7M06MIIXAtr9jsrLs2Glflgf2vMQRepxawOdQ==", + "version": "1.5.331", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.331.tgz", + "integrity": "sha512-IbxXrsTlD3hRodkLnbxAPP4OuJYdWCeM3IOdT+CpcMoIwIoDfCmRpEtSPfwBXxVkg9xmBeY7Lz2Eo2TDn/HC3Q==", "dev": true, + "license": "ISC", "peer": true }, "node_modules/emojis-list": { @@ -458,31 +517,34 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", + "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" } }, "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=6" @@ -550,13 +612,25 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, + "license": "MIT", "peer": true }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", "peer": true }, "node_modules/glob-to-regexp": { @@ -564,6 +638,7 @@ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true, + "license": "BSD-2-Clause", "peer": true }, "node_modules/graceful-fs": { @@ -571,6 +646,7 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, + "license": "ISC", "peer": true }, "node_modules/has-flag": { @@ -578,6 +654,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=8" @@ -588,6 +665,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/node": "*", @@ -606,10 +684,11 @@ "peer": true }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/json5": { @@ -625,13 +704,18 @@ } }, "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/loader-utils": { @@ -653,6 +737,7 @@ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/mime-db": { @@ -704,70 +789,44 @@ "peer": true }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.37", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", + "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, + "license": "ISC", "peer": true }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "license": "MIT", "peer": true, "engines": { - "node": ">=6" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "peer": true, - "dependencies": { - "safe-buffer": "^5.1.0" + "node": ">=0.10.0" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peer": true - }, "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 10.13.0" @@ -777,21 +836,12 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "peer": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "peer": true, "engines": { "node": ">=0.10.0" @@ -802,6 +852,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "buffer-from": "^1.0.0", @@ -813,6 +864,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "has-flag": "^4.0.0" @@ -825,24 +877,30 @@ } }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz", + "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.1.tgz", + "integrity": "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==", "dev": true, + "license": "BSD-2-Clause", "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -854,17 +912,17 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz", + "integrity": "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" + "schema-utils": "^4.3.0", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" @@ -894,16 +952,17 @@ "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -919,10 +978,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "peer": true, "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -931,21 +991,12 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "peer": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -956,36 +1007,38 @@ } }, "node_modules/webpack": { - "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", + "version": "5.105.4", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.4.tgz", + "integrity": "sha512-jTywjboN9aHxFlToqb0K0Zs9SbBoW4zRUlGzI2tYNxVYcEi/IPpn+Xi4ye5jTLvX2YeLuic/IvxNot+Q1jMoOw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.16.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", - "es-module-lexer": "^1.2.1", + "enhanced-resolve": "^5.20.0", + "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.17", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.4" }, "bin": { "webpack": "bin/webpack.js" @@ -1004,10 +1057,11 @@ } }, "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz", + "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=10.13.0" diff --git a/plugins/timecode/package-lock.json b/plugins/timecode/package-lock.json index f67e7885..af285bca 100644 --- a/plugins/timecode/package-lock.json +++ b/plugins/timecode/package-lock.json @@ -19,29 +19,6 @@ "bridge": "^0.0.1" } }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", @@ -105,6 +82,29 @@ "node": ">= 14" } }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/cacache": { "version": "20.0.3", "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.3.tgz", @@ -417,16 +417,16 @@ } }, "node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.5" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -726,9 +726,9 @@ } }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -848,9 +848,9 @@ } }, "node_modules/tar": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz", - "integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==", + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", + "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": {