From 42f6b4d25c99a71ff55b234a0cefe5ddc6b78c01 Mon Sep 17 00:00:00 2001 From: nymkappa Date: Thu, 30 Apr 2026 17:18:46 +0200 Subject: [PATCH 01/17] [accelerator] use new preferred alias in documentation --- frontend/src/app/docs/api-docs/api-docs-data.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/docs/api-docs/api-docs-data.ts b/frontend/src/app/docs/api-docs/api-docs-data.ts index 28ec714b1..caa5570ce 100644 --- a/frontend/src/app/docs/api-docs/api-docs-data.ts +++ b/frontend/src/app/docs/api-docs/api-docs-data.ts @@ -11982,7 +11982,7 @@ export const restApiDocsData = [ codeSampleMainnet: { esModule: [], commonJS: [], - curl: ['txInput=ee13ebb99632377c15c94980357f674d285ac413452050031ea6dcd3e9b2dc29'], + curl: ['txid=ee13ebb99632377c15c94980357f674d285ac413452050031ea6dcd3e9b2dc29'], headers: 'X-Mempool-Auth: stacksats', response: `{ "txSummary": { @@ -12339,7 +12339,7 @@ export const restApiDocsData = [ codeSampleMainnet: { esModule: [], commonJS: [], - curl: ['txInput=ee13ebb99632377c15c94980357f674d285ac413452050031ea6dcd3e9b2dc29&userBid=21000000'], + curl: ['txid=ee13ebb99632377c15c94980357f674d285ac413452050031ea6dcd3e9b2dc29&maxBidBoost=21000000'], headers: 'X-Mempool-Auth: stacksats', response: `HTTP/1.1 200 OK`, }, @@ -12410,7 +12410,7 @@ export const restApiDocsData = [ codeSampleMainnet: { esModule: [], commonJS: [], - curl: ['txInput=ee13ebb99632377c15c94980357f674d285ac413452050031ea6dcd3e9b2dc29&type=time_delay&value=0.5'], + curl: ['txid=ee13ebb99632377c15c94980357f674d285ac413452050031ea6dcd3e9b2dc29&type=time_delay&value=0.5'], headers: 'X-Mempool-Auth: stacksats', response: `HTTP/1.1 200 OK`, }, From 400c0f14068871fb74f23ced33d905271c436982 Mon Sep 17 00:00:00 2001 From: mononaut Date: Sun, 3 May 2026 08:37:09 +0000 Subject: [PATCH 02/17] add cluster diagram preview to effective fee rate row --- .../cluster-diagram.component.html | 106 ++++----- .../cluster-diagram.component.scss | 29 +++ .../cluster-diagram.component.ts | 78 ++++++- .../cluster-diagram/cluster-renderer.ts | 201 +++++++++++++----- .../transaction-details.component.html | 32 +-- .../transaction-details.component.scss | 27 +++ 6 files changed, 349 insertions(+), 124 deletions(-) diff --git a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.html b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.html index 53cd9861b..359116577 100644 --- a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.html +++ b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.html @@ -1,5 +1,5 @@ -
- +
+ - + + - - {{ outline.feerate | feeRounding }} sat/vB - - - - - - - - - - - {{ node.feerate | feeRounding }} + + {{ outline.feerate | feeRounding }} sat/vB - + + + + + + + + + + + + + + {{ node.feerate | feeRounding }} + + +
| null = null; + private resizeObserver: ResizeObserver | null = null; + private lastObservedWidth = 0; constructor( private router: Router, @@ -52,8 +55,7 @@ export class ClusterDiagramComponent implements OnChanges { ngOnChanges(changes: SimpleChanges): void { if (!this.cluster?.txs?.length) { return; } - this.activeChunkIndex = this.cluster.chunkIndex; - const clusterChanged = changes['cluster']; + const clusterChanged = changes['cluster'] || changes['preview']; if (clusterChanged) { this.computeLayout(); } @@ -61,8 +63,28 @@ export class ClusterDiagramComponent implements OnChanges { } private computeLayout(): void { - this.txs = this.cluster.txs; - this.chunks = this.cluster.chunks; + if (this.preview && this.cluster.chunks.length > 0) { + const activeChunk = this.cluster.chunks[this.cluster.chunkIndex]; + const memberSet = new Set(activeChunk.txs); + const remap = new Map(); + activeChunk.txs.forEach((origIdx, newIdx) => remap.set(origIdx, newIdx)); + + this.txs = activeChunk.txs.map(origIdx => ({ + ...this.cluster.txs[origIdx], + parents: this.cluster.txs[origIdx].parents + .filter(p => memberSet.has(p)) + .map(p => remap.get(p) as number), + })); + this.chunks = [{ + txs: this.txs.map((_, i) => i), + feerate: activeChunk.feerate, + }]; + this.activeChunkIndex = 0; + } else { + this.txs = this.cluster.txs; + this.chunks = this.cluster.chunks; + this.activeChunkIndex = this.cluster.chunkIndex; + } this.gridLayout = computeGridLayout(this.txs, this.chunks); } @@ -88,6 +110,8 @@ export class ClusterDiagramComponent implements OnChanges { txids: this.txs.map(tx => tx.txid), chunkFeerates: this.chunks.map(c => c.feerate), getColor, + preview: this.preview, + idPrefix: this.idPrefix, }); this.nodes = result.nodes; @@ -95,9 +119,11 @@ export class ClusterDiagramComponent implements OnChanges { this.chunkOutlines = result.chunkOutlines; this.svgWidth = result.svgWidth; this.svgHeight = result.svgHeight; + this.svgViewBox = result.viewBox; } onNodeEnter(node: RenderedNode, event: MouseEvent): void { + if (this.preview) { return; } this.hoverNode = node; this.clearHighlights(); node.hovered = true; @@ -115,17 +141,20 @@ export class ClusterDiagramComponent implements OnChanges { } onNodeMove(event: MouseEvent): void { + if (this.preview) { return; } this.updateTooltipPosition(event); this.cd.markForCheck(); } onNodeLeave(): void { + if (this.preview) { return; } this.hoverNode = null; this.clearHighlights(); this.cd.markForCheck(); } onEdgeEnter(edgeIndex: number): void { + if (this.preview) { return; } this.clearHighlights(); const edge = this.edges[edgeIndex]; edge.highlighted = true; @@ -135,11 +164,13 @@ export class ClusterDiagramComponent implements OnChanges { } onEdgeLeave(): void { + if (this.preview) { return; } this.clearHighlights(); this.cd.markForCheck(); } onNodeClick(node: RenderedNode): void { + if (this.preview) { return; } const network = this.stateService.network; const prefix = network && network !== 'mainnet' ? `/${network}` : ''; this.router.navigate([prefix + '/tx/', node.tx.txid]); @@ -200,6 +231,31 @@ export class ClusterDiagramComponent implements OnChanges { @HostListener('window:resize') onResize(): void { + this.scheduleRerender(); + } + + ngAfterViewInit(): void { + if (typeof ResizeObserver !== 'undefined' && this.graphContainer?.nativeElement) { + this.resizeObserver = new ResizeObserver(entries => { + const width = entries[0]?.contentRect.width ?? 0; + if (Math.abs(width - this.lastObservedWidth) < 1) { return; } + this.lastObservedWidth = width; + this.scheduleRerender(); + }); + this.resizeObserver.observe(this.graphContainer.nativeElement); + } + } + + ngOnDestroy(): void { + this.resizeObserver?.disconnect(); + this.resizeObserver = null; + if (this.resizeTimer !== null) { + clearTimeout(this.resizeTimer); + this.resizeTimer = null; + } + } + + private scheduleRerender(): void { if (this.resizeTimer !== null) { clearTimeout(this.resizeTimer); } diff --git a/frontend/src/app/components/cluster-diagram/cluster-renderer.ts b/frontend/src/app/components/cluster-diagram/cluster-renderer.ts index fdd509043..7bc3ab356 100644 --- a/frontend/src/app/components/cluster-diagram/cluster-renderer.ts +++ b/frontend/src/app/components/cluster-diagram/cluster-renderer.ts @@ -7,6 +7,9 @@ export interface RenderedNode { y: number; rectX: number; rectY: number; + width: number; + height: number; + rx: number; color: string; chunkIndex: number; feerate: number; @@ -14,6 +17,7 @@ export interface RenderedNode { isCurrent: boolean; hovered: boolean; related: boolean; + visible: boolean; } export interface RenderedEdge { @@ -31,6 +35,7 @@ export interface RenderedEdge { x2: number; y2: number; highlighted: boolean; + visible: boolean; } export interface RenderedChunkOutline { @@ -50,6 +55,8 @@ export interface RenderParams { txids: string[]; chunkFeerates: number[]; getColor: (feerate: number) => string; + preview?: boolean; + idPrefix: string; } interface RenderResult { @@ -58,6 +65,19 @@ interface RenderResult { chunkOutlines: RenderedChunkOutline[]; svgWidth: number; svgHeight: number; + viewBox: string | null; +} + +interface RenderDimensions { + nodeW: number; + nodeH: number; + cellPadY: number; + minCellW: number; + maxCellW: number; + marginX: number; + marginY: number; + laneSpacing: number; + nodeRx: number; } interface GridGeometry { @@ -68,38 +88,57 @@ interface GridGeometry { cellW: number; totalCols: number; totalRows: number; + dim: RenderDimensions; } -export const NODE_W = 64; -export const NODE_H = 30; -const MIN_CELL_W = 80; -const MAX_CELL_W = 120; -const CELL_PAD_Y = 16; -const MARGIN_X = 20; -const MARGIN_Y = 30; -const LANE_SPACING = 6; -const MIN_GUTTER_W = 3 * LANE_SPACING; -const MIN_GUTTER_H = 3 * LANE_SPACING; +const DEFAULT_DIMENSIONS: RenderDimensions = { + nodeW: 64, + nodeH: 30, + cellPadY: 16, + minCellW: 80, + maxCellW: 120, + marginX: 20, + marginY: 30, + laneSpacing: 6, + nodeRx: 6, +}; + +const PREVIEW_DIMENSIONS: RenderDimensions = { + nodeW: 10, + nodeH: 10, + cellPadY: 2, + minCellW: 18, + maxCellW: 80, + marginX: 3, + marginY: 3, + laneSpacing: 2, + nodeRx: 2, +}; + +const PREVIEW_VIEWPORT_HEIGHT = 48; const OUTLINE_PAD = 6; export function renderLayout(layout: GridLayout, params: RenderParams): RenderResult { if (layout.nodes.length === 0) { - return { nodes: [], edges: [], chunkOutlines: [], svgWidth: 0, svgHeight: 0 }; + return { nodes: [], edges: [], chunkOutlines: [], svgWidth: 0, svgHeight: 0, viewBox: null }; } - const cellH = NODE_H + CELL_PAD_Y; + const dim = params.preview ? PREVIEW_DIMENSIONS : DEFAULT_DIMENSIONS; + const minGutterW = 3 * dim.laneSpacing; + const minGutterH = 3 * dim.laneSpacing; + const cellH = dim.nodeH + dim.cellPadY; const rowHeights: number[] = []; for (let r = 0; r < layout.rows; r++) { const laneCount = (layout.rowLaneCounts && layout.rowLaneCounts[r]) || 0; if (r % 2 === 0) { - rowHeights.push(Math.max(cellH, (laneCount + 1) * LANE_SPACING)); + rowHeights.push(Math.max(cellH, (laneCount + 1) * dim.laneSpacing)); } else { - rowHeights.push(Math.max(MIN_GUTTER_H, (laneCount + 1) * LANE_SPACING)); + rowHeights.push(Math.max(minGutterH, (laneCount + 1) * dim.laneSpacing)); } } - const rowTopY: number[] = [MARGIN_Y]; + const rowTopY: number[] = [dim.marginY]; for (let r = 1; r < layout.rows; r++) { rowTopY.push(rowTopY[r - 1] + rowHeights[r - 1]); } @@ -107,16 +146,24 @@ export function renderLayout(layout: GridLayout, params: RenderParams): RenderRe const gutterWidths: number[] = []; for (let c = 0; c < layout.cols - 1; c++) { const laneCount = (layout.colLaneCounts && layout.colLaneCounts[c]) || 0; - gutterWidths.push(Math.max(MIN_GUTTER_W, (laneCount + 1) * LANE_SPACING)); + gutterWidths.push(Math.max(minGutterW, (laneCount + 1) * dim.laneSpacing)); } const totalGutterW = gutterWidths.reduce((a, b) => a + b, 0); - const fixedWidth = MARGIN_X * 2 + totalGutterW; - const cellW = layout.cols > 0 - ? Math.max(MIN_CELL_W, Math.min(MAX_CELL_W, (params.containerWidth - fixedWidth) / layout.cols)) - : MIN_CELL_W; + const fixedWidth = dim.marginX * 2 + totalGutterW; + let cellW: number; + if (params.preview) { + const activeCols = activeChunkColCount(layout, params.activeChunkIndex); + const denom = Math.max(1, activeCols); + cellW = Math.max(dim.minCellW, Math.min(dim.maxCellW, + (params.containerWidth - dim.marginX * 2) / denom)); + } else if (layout.cols > 0) { + cellW = Math.max(dim.minCellW, Math.min(dim.maxCellW, (params.containerWidth - fixedWidth) / layout.cols)); + } else { + cellW = dim.minCellW; + } - const colLeftX: number[] = [MARGIN_X]; + const colLeftX: number[] = [dim.marginX]; for (let c = 1; c < layout.cols; c++) { colLeftX.push(colLeftX[c - 1] + cellW + gutterWidths[c - 1]); } @@ -124,16 +171,66 @@ export function renderLayout(layout: GridLayout, params: RenderParams): RenderRe const geo: GridGeometry = { colLeftX, rowTopY, rowHeights, gutterWidths, cellW, totalCols: layout.cols, totalRows: layout.rows, + dim, }; const nodes = renderNodes(layout.nodes, params, geo); - const edges = renderEdges(layout.edges, nodes, geo); - const chunkOutlines = renderChunkOutlines(layout.chunks, params, geo); + const edges = renderEdges(layout.edges, nodes, geo, params.idPrefix); + const chunkOutlines = params.preview ? [] : renderChunkOutlines(layout.chunks, params, geo); - const svgWidth = MARGIN_X * 2 + layout.cols * cellW + totalGutterW; - const svgHeight = rowTopY[layout.rows - 1] + rowHeights[layout.rows - 1] + MARGIN_Y; + const fullWidth = dim.marginX * 2 + layout.cols * cellW + totalGutterW; + const fullHeight = rowTopY[layout.rows - 1] + rowHeights[layout.rows - 1] + dim.marginY; - return { nodes, edges, chunkOutlines, svgWidth, svgHeight }; + if (params.preview) { + const selected = nodes.find(n => n.isCurrent && n.visible) ?? nodes.find(n => n.visible); + if (!selected) { + return { nodes, edges, chunkOutlines, svgWidth: fullWidth, svgHeight: fullHeight, viewBox: null }; + } + + const vbHeight = PREVIEW_VIEWPORT_HEIGHT; + const vbWidth = Math.max(dim.minCellW * 3, params.containerWidth || dim.minCellW * 8); + + let activeMinX = Infinity, activeMaxX = -Infinity; + let activeMinY = Infinity, activeMaxY = -Infinity; + for (const n of nodes) { + if (n.visible) { + activeMinX = Math.min(activeMinX, n.rectX); + activeMaxX = Math.max(activeMaxX, n.rectX + n.width); + activeMinY = Math.min(activeMinY, n.rectY); + activeMaxY = Math.max(activeMaxY, n.rectY + n.height); + } + } + const pad = dim.marginX; + const chunkFits = isFinite(activeMinX) && (activeMaxX - activeMinX) + 2 * pad <= vbWidth; + const vbX = chunkFits + ? (activeMinX + activeMaxX) / 2 - vbWidth / 2 + : selected.x - vbWidth / 2; + const chunkFitsVertically = isFinite(activeMinY) && (activeMaxY - activeMinY) + 2 * dim.marginY <= vbHeight; + const vbY = chunkFitsVertically + ? (activeMinY + activeMaxY) / 2 - vbHeight / 2 + : selected.y - vbHeight / 2; + + return { + nodes, edges, chunkOutlines, + svgWidth: vbWidth, + svgHeight: vbHeight, + viewBox: `${vbX} ${vbY} ${vbWidth} ${vbHeight}`, + }; + } + + return { nodes, edges, chunkOutlines, svgWidth: fullWidth, svgHeight: fullHeight, viewBox: null }; +} + +function activeChunkColCount(layout: GridLayout, activeChunkIndex: number): number { + let minCol = Infinity, maxCol = -Infinity; + for (const n of layout.nodes) { + if (n.chunkIndex === activeChunkIndex) { + if (n.col < minCol) { minCol = n.col; } + if (n.col > maxCol) { maxCol = n.col; } + } + } + if (!isFinite(minCol)) { return layout.cols; } + return maxCol - minCol + 1; } function geoCellX(geo: GridGeometry, col: number): number { @@ -141,7 +238,7 @@ function geoCellX(geo: GridGeometry, col: number): number { } function geoCellY(geo: GridGeometry, row: number): number { - if (row < 0 || row >= geo.totalRows) { return MARGIN_Y; } + if (row < 0 || row >= geo.totalRows) { return geo.dim.marginY; } return geo.rowTopY[row] + geo.rowHeights[row] / 2; } @@ -154,7 +251,7 @@ function geoCellLeft(geo: GridGeometry, col: number): number { } function geoCellTop(geo: GridGeometry, row: number): number { - if (row < 0 || row >= geo.totalRows) { return MARGIN_Y; } + if (row < 0 || row >= geo.totalRows) { return geo.dim.marginY; } return geo.rowTopY[row]; } @@ -163,7 +260,7 @@ function geoCellRight(geo: GridGeometry, col: number): number { } function geoCellBottom(geo: GridGeometry, row: number): number { - if (row < 0 || row >= geo.totalRows) { return MARGIN_Y; } + if (row < 0 || row >= geo.totalRows) { return geo.dim.marginY; } return geo.rowTopY[row] + geo.rowHeights[row]; } @@ -186,6 +283,7 @@ function renderNodes(gridNodes: GridNode[], params: RenderParams, geo: GridGeome const feerate = params.txFees[gn.index] / (params.txWeights[gn.index] / 4); const color = params.getColor(feerate); const inactive = gn.chunkIndex !== params.activeChunkIndex; + const visible = !params.preview || !inactive; return { index: gn.index, @@ -195,8 +293,11 @@ function renderNodes(gridNodes: GridNode[], params: RenderParams, geo: GridGeome weight: params.txWeights[gn.index], }, x, y, - rectX: x - NODE_W / 2, - rectY: y - NODE_H / 2, + rectX: x - geo.dim.nodeW / 2, + rectY: y - geo.dim.nodeH / 2, + width: geo.dim.nodeW, + height: geo.dim.nodeH, + rx: geo.dim.nodeRx, color, chunkIndex: gn.chunkIndex, feerate, @@ -204,6 +305,7 @@ function renderNodes(gridNodes: GridNode[], params: RenderParams, geo: GridGeome isCurrent: params.txids[gn.index] === params.currentTxid, hovered: false, related: false, + visible, }; }); } @@ -216,8 +318,9 @@ interface FanInfo { function computeFanInfos( gridEdges: GridEdge[], side: 'exit' | 'entry', + dim: RenderDimensions, ): (FanInfo | undefined)[] { - const nodeHalfH = NODE_H / 2; + const nodeHalfH = dim.nodeH / 2; const nodeKey = side === 'exit' ? 'parent' : 'child'; const groups = new Map(); @@ -241,7 +344,7 @@ function computeFanInfos( for (const ei of edgeIndices) { const slot = side === 'exit' ? gridEdges[ei].exitSlot : gridEdges[ei].entrySlot; const count = side === 'exit' ? gridEdges[ei].exitCount : gridEdges[ei].entryCount; - if (Math.abs(slotToOffset(slot, count)) > nodeHalfH) { + if (Math.abs(slotToOffset(slot, count, dim)) > nodeHalfH) { anyNeedsFan = true; break; } @@ -250,14 +353,14 @@ function computeFanInfos( if (!anyNeedsFan) { continue; } const nodeCount = edgeIndices.length; - const edgeSpacing = (NODE_H - 2) / Math.max(1, nodeCount - 1); + const edgeSpacing = (dim.nodeH - 2) / Math.max(1, nodeCount - 1); let maxDy = 0; const nodeEdgeOffsets: number[] = []; for (let k = 0; k < edgeIndices.length; k++) { const slot = side === 'exit' ? gridEdges[edgeIndices[k]].exitSlot : gridEdges[edgeIndices[k]].entrySlot; const count = side === 'exit' ? gridEdges[edgeIndices[k]].exitCount : gridEdges[edgeIndices[k]].entryCount; - const laneOffset = slotToOffset(slot, count); + const laneOffset = slotToOffset(slot, count, dim); const nodeEdgeOffset = (k - (nodeCount - 1) / 2) * edgeSpacing; nodeEdgeOffsets.push(nodeEdgeOffset); maxDy = Math.max(maxDy, Math.abs(laneOffset - nodeEdgeOffset)); @@ -275,9 +378,10 @@ function computeFanInfos( function renderEdges( gridEdges: GridEdge[], renderedNodes: RenderedNode[], geo: GridGeometry, + idPrefix: string, ): RenderedEdge[] { - const exitFanInfos = computeFanInfos(gridEdges, 'exit'); - const entryFanInfos = computeFanInfos(gridEdges, 'entry'); + const exitFanInfos = computeFanInfos(gridEdges, 'exit', geo.dim); + const entryFanInfos = computeFanInfos(gridEdges, 'entry', geo.dim); return gridEdges.map((ge, idx) => { const pNode = renderedNodes[ge.parent]; @@ -293,8 +397,8 @@ function renderEdges( parentIndex: ge.parent, childIndex: ge.child, path, - gradientId: `edge-grad-${idx}`, - markerId: `edge-arrow-${idx}`, + gradientId: `${idPrefix}-edge-grad-${idx}`, + markerId: `${idPrefix}-edge-arrow-${idx}`, parentColor: pNode.color, childColor: cNode.color, parentInactive: pNode.inactive, @@ -302,6 +406,7 @@ function renderEdges( x1: first.x, y1: first.y, x2: last.x, y2: last.y, highlighted: false, + visible: pNode.visible && cNode.visible, }; }); } @@ -319,11 +424,11 @@ function waypointsToPixels( const wp = edge.waypoints; if (wp.length < 2) { return []; } - const exitOffset = slotToOffset(edge.exitSlot, edge.exitCount); - const entryOffset = slotToOffset(edge.entrySlot, edge.entryCount); + const exitOffset = slotToOffset(edge.exitSlot, edge.exitCount, geo.dim); + const entryOffset = slotToOffset(edge.entrySlot, edge.entryCount, geo.dim); const points: PathPoint[] = []; - const startNodeX = geoCellX(geo, wp[0].col) + NODE_W / 2; + const startNodeX = geoCellX(geo, wp[0].col) + geo.dim.nodeW / 2; const cy0 = geoCellY(geo, wp[0].row); if (exitFan) { @@ -336,7 +441,7 @@ function waypointsToPixels( let curY = cy0 + exitOffset; for (let i = 0; i < wp.length - 1; i++) { const vInfo = edge.verticalSlots[i]; - const gx = geoGutterCenterX(geo, wp[i].col) + slotToOffset(vInfo.slot, vInfo.count); + const gx = geoGutterCenterX(geo, wp[i].col) + slotToOffset(vInfo.slot, vInfo.count, geo.dim); const isLast = i === wp.length - 2; let nextY: number; @@ -344,7 +449,7 @@ function waypointsToPixels( nextY = geoCellY(geo, wp[i + 1].row) + entryOffset; } else { const hInfo = edge.horizontalSlots[i]; - nextY = geoCellY(geo, wp[i + 1].row) + slotToOffset(hInfo.slot, hInfo.count); + nextY = geoCellY(geo, wp[i + 1].row) + slotToOffset(hInfo.slot, hInfo.count, geo.dim); } if (points[points.length - 1].x !== gx) { @@ -358,12 +463,12 @@ function waypointsToPixels( if (!isLast) { const nextVInfo = edge.verticalSlots[i + 1]; - const nextGx = geoGutterCenterX(geo, wp[i + 1].col) + slotToOffset(nextVInfo.slot, nextVInfo.count); + const nextGx = geoGutterCenterX(geo, wp[i + 1].col) + slotToOffset(nextVInfo.slot, nextVInfo.count, geo.dim); points.push({ x: nextGx, y: curY }); } } - const endNodeX = geoCellX(geo, wp[wp.length - 1].col) - NODE_W / 2; + const endNodeX = geoCellX(geo, wp[wp.length - 1].col) - geo.dim.nodeW / 2; const cyLast = geoCellY(geo, wp[wp.length - 1].row); if (entryFan) { @@ -376,9 +481,9 @@ function waypointsToPixels( return points; } -function slotToOffset(slot: number, count: number): number { +function slotToOffset(slot: number, count: number, dim: RenderDimensions): number { if (count <= 1) { return 0; } - return (slot - (count - 1) / 2) * LANE_SPACING; + return (slot - (count - 1) / 2) * dim.laneSpacing; } function buildEdgePath(points: PathPoint[]): string { diff --git a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html index 6b1082668..a639a85d3 100644 --- a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html +++ b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html @@ -252,24 +252,26 @@ Effective fee rate } -
- @if (accelerationInfo?.acceleratedFeeRate && (!tx.effectiveFeePerVsize || accelerationInfo.acceleratedFeeRate >= tx.effectiveFeePerVsize || tx.acceleration)) { - - } @else { - - } +
+
+ @if (accelerationInfo?.acceleratedFeeRate && (!tx.effectiveFeePerVsize || accelerationInfo.acceleratedFeeRate >= tx.effectiveFeePerVsize || tx.acceleration)) { + + } @else { + + } - @if (tx?.status?.confirmed && !tx.acceleration && !accelerationInfo && tx.fee && tx.effectiveFeePerVsize) { - + @if (tx?.status?.confirmed && !tx.acceleration && !accelerationInfo && tx.fee && tx.effectiveFeePerVsize) { + + } +
+ @if (cpfpInfo?.cluster && tx?.txid) { +
+ +
+ } @else if (hasCpfp) { + }
- @if (hasCpfp) { - @if (cpfpInfo?.cluster) { - - } @else { - - } - } } diff --git a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss index a062f84a4..4c9a609e6 100644 --- a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss +++ b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss @@ -164,3 +164,30 @@ opacity: 0.5; pointer-events: none; } + +.effective-fee-row { + display: flex; + align-items: center; + gap: 0.5rem; + flex-wrap: wrap; + + .effective-fee-container { + flex: 0 0 auto; + } +} + +.cluster-preview-inline { + position: relative; + flex: 1 1 80px; + min-width: 80px; + max-width: 100%; + display: flex; + align-items: center; + overflow: visible; + margin: -0.75rem -0.75rem -0.75rem 0; + + app-cluster-diagram { + display: block; + width: 100%; + } +} From 2cfa7b71a88b836d9cff5647f115c99ac945931a Mon Sep 17 00:00:00 2001 From: mononaut Date: Sun, 3 May 2026 08:41:05 +0000 Subject: [PATCH 03/17] cluster preview toggle functionality --- .../cluster-diagram.component.scss | 4 ++ .../transaction-details.component.html | 17 ++++++- .../transaction-details.component.scss | 48 ++++++++++++++++++- .../transaction-details.component.ts | 11 +++++ .../transaction/transaction-raw.component.ts | 16 ++----- .../transaction/transaction.component.html | 12 +++-- .../transaction/transaction.component.ts | 48 ++++++++++++------- frontend/src/app/shared/shared.module.ts | 4 +- 8 files changed, 121 insertions(+), 39 deletions(-) diff --git a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss index 418c4df46..735ce0327 100644 --- a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss +++ b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss @@ -15,6 +15,10 @@ overflow: hidden; pointer-events: none; border-radius: 4px; + background-color: var(--cluster-preview-background, var(--stat-box-bg)); + box-shadow: var(--cluster-preview-shadow, none); + cursor: var(--cluster-preview-cursor, default); + transition: box-shadow 150ms ease, background-color 150ms ease; svg { display: block; diff --git a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html index a639a85d3..2c8c2eb82 100644 --- a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html +++ b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html @@ -265,9 +265,22 @@ }
@if (cpfpInfo?.cluster && tx?.txid) { -
- +
+ +
+ +

This transaction belongs to a chunk of {{ clusterPreviewStats.chunkSize }} transaction{{ clusterPreviewStats.chunkSize === 1 ? '' : 's' }}, with combined effective fee rate {{ clusterPreviewStats.chunkFeerate | feeRounding }} sat/vB.

+

In a mempool cluster containing {{ clusterPreviewStats.otherChunks }} other chunk{{ clusterPreviewStats.otherChunks === 1 ? '' : 's' }}.

+

Click for more details.

+
} @else if (hasCpfp) { } diff --git a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss index 4c9a609e6..06f9cb602 100644 --- a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss +++ b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss @@ -185,9 +185,55 @@ align-items: center; overflow: visible; margin: -0.75rem -0.75rem -0.75rem 0; + cursor: pointer; - app-cluster-diagram { + .cluster-preview-diagram { display: block; width: 100%; + --cluster-preview-cursor: pointer; + } + + .cluster-preview-expand { + position: absolute; + top: 4px; + right: 4px; + color: var(--info); + font-size: 0.85em; + opacity: 0; + transition: opacity 150ms ease; + pointer-events: none; + z-index: 1; + } + + &:focus-visible { outline: none; } + + &:hover .cluster-preview-expand, + &:focus-visible .cluster-preview-expand { + opacity: 1; + } + + &:hover .cluster-preview-diagram, + &:focus-visible .cluster-preview-diagram { + --cluster-preview-background: color-mix(in srgb, var(--info) 8%, var(--stat-box-bg)); + --cluster-preview-shadow: 0 0 0 1px var(--info), 0 0 8px color-mix(in srgb, var(--info) 35%, transparent); + } +} + +::ng-deep .cluster-preview-ngb-tooltip .tooltip-inner { + text-align: left; + max-width: 320px; + padding: 10px 12px; + + p { + margin: 0 0 6px; + line-height: 1.35; + + &:last-child { margin-bottom: 0; } + + &.hint { + margin-top: 8px; + opacity: 0.8; + font-style: italic; + } } } diff --git a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.ts b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.ts index 0b15072cf..39272b684 100644 --- a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.ts +++ b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.ts @@ -40,6 +40,7 @@ export class TransactionDetailsComponent implements OnInit { @Input() isCached: boolean; @Input() ETA$: Observable; @Input() unbroadcasted: boolean; + @Input() cpfpMode: boolean = false; @Output() accelerateClicked = new EventEmitter(); @Output() toggleCpfp$ = new EventEmitter(); @@ -55,4 +56,14 @@ export class TransactionDetailsComponent implements OnInit { toggleCpfp(): void { this.toggleCpfp$.emit(); } + + get clusterPreviewStats(): { chunkSize: number; chunkFeerate: number; otherChunks: number } { + const cluster = this.cpfpInfo?.cluster; + const chunk = cluster?.chunks[cluster.chunkIndex]; + return { + chunkSize: chunk?.txs.length ?? 0, + chunkFeerate: chunk?.feerate ?? 0, + otherChunks: Math.max(0, (cluster?.chunks.length ?? 0) - 1), + }; + } } diff --git a/frontend/src/app/components/transaction/transaction-raw.component.ts b/frontend/src/app/components/transaction/transaction-raw.component.ts index 9c295f0a5..8df3b5136 100644 --- a/frontend/src/app/components/transaction/transaction-raw.component.ts +++ b/frontend/src/app/components/transaction/transaction-raw.component.ts @@ -68,7 +68,7 @@ export class TransactionRawComponent implements OnInit, OnDestroy { fetchCpfp: boolean; cpfpInfo: CpfpInfo | null; hasCpfp: boolean = false; - cpfpMode: 'advanced' | 'simple' | null = null; + cpfpMode: boolean = false; mempoolBlocksSubscription: Subscription; constructor( @@ -90,10 +90,7 @@ export class TransactionRawComponent implements OnInit, OnDestroy { this.seoService.setTitle($localize`:@@d7f92e6fe26fba6fff568cbdae5db4a5c8c6a55c:Preview Transaction`); this.seoService.setDescription($localize`:@@meta.description.preview-tx:Preview a transaction to the Bitcoin${seoDescriptionNetwork(this.stateService.network)} network using the transaction's raw hex data.`); this.websocketService.want(['blocks', 'mempool-blocks']); - const cpfpParam = this.route.snapshot.queryParams['cpfp']; - if (cpfpParam === 'advanced' || cpfpParam === 'simple') { - this.cpfpMode = cpfpParam; - } + this.cpfpMode = this.route.snapshot.queryParams['cpfp'] === 'true'; this.pushTxForm = this.formBuilder.group({ txRaw: ['', Validators.required], }); @@ -394,15 +391,10 @@ export class TransactionRawComponent implements OnInit, OnDestroy { } toggleCpfp() { - const newMode = this.cpfpMode ? null : (this.cpfpInfo?.cluster ? 'advanced' : 'simple'); - this.updateCpfpMode(newMode); - } - - private updateCpfpMode(mode: 'advanced' | 'simple' | null) { - this.cpfpMode = mode; + this.cpfpMode = !this.cpfpMode; this.router.navigate([], { relativeTo: this.route, - queryParams: { cpfp: mode }, + queryParams: { cpfp: this.cpfpMode ? 'true' : null }, queryParamsHandling: 'merge', preserveFragment: true, replaceUrl: true, diff --git a/frontend/src/app/components/transaction/transaction.component.html b/frontend/src/app/components/transaction/transaction.component.html index a854fb7b5..d9f6d4be8 100644 --- a/frontend/src/app/components/transaction/transaction.component.html +++ b/frontend/src/app/components/transaction/transaction.component.html @@ -68,6 +68,7 @@ [hasEffectiveFeeRate]="hasEffectiveFeeRate" [cpfpInfo]="cpfpInfo" [hasCpfp]="hasCpfp" + [cpfpMode]="cpfpMode" [accelerationInfo]="accelerationInfo" [replaced]="replaced" [isCached]="isCached" @@ -81,13 +82,14 @@ +
-
-
-

Cluster

-

Related Transactions

-
+
+

Cluster

+

Related Transactions

+ +
(); transactionTimes$ = new Subject(); @@ -197,6 +197,13 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { } } + @ViewChild('cluster') + set clusterAnchor(element: ElementRef | null | undefined) { + if (element) { + setTimeout(() => { this.applyFragment(); }, 0); + } + } + constructor( private route: ActivatedRoute, private router: Router, @@ -221,10 +228,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { ngOnInit() { this.enterpriseService.page(); this.isDetailsOpen = this.route.snapshot.queryParams['showDetails'] === 'true'; - const cpfpParam = this.route.snapshot.queryParams['cpfp']; - if (cpfpParam === 'advanced' || cpfpParam === 'simple') { - this.cpfpMode = cpfpParam; - } + this.cpfpMode = this.isCpfpParamEnabled(this.route.snapshot.queryParams['cpfp']); const urlParams = new URLSearchParams(window.location.search); this.forceAccelerationSummary = !!urlParams.get('cash_request_id'); @@ -1104,8 +1108,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { this.auditStatus = null; this.accelerationPositions = null; this.isDetailsOpen = this.route.snapshot.queryParams['showDetails'] === 'true'; - const cpfpParam = this.route.snapshot.queryParams['cpfp']; - this.cpfpMode = (cpfpParam === 'advanced' || cpfpParam === 'simple') ? cpfpParam : null; + this.cpfpMode = this.isCpfpParamEnabled(this.route.snapshot.queryParams['cpfp']); document.body.scrollTo(0, 0); this.isAcceleration = false; this.isAccelerated$.next(this.isAcceleration); @@ -1124,19 +1127,28 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { } toggleCpfp() { - const newMode = this.cpfpMode ? null : (this.cpfpInfo?.cluster ? 'advanced' : 'simple'); - this.updateCpfpMode(newMode); + this.cpfpMode = !this.cpfpMode; + if (this.cpfpInfo?.cluster) { + this.router.navigate([], { + relativeTo: this.route, + queryParams: { cpfp: this.cpfpMode ? 'true' : null }, + queryParamsHandling: 'merge', + fragment: this.cpfpMode ? 'cluster' : undefined, + replaceUrl: true, + }); + } else { + this.router.navigate([], { + relativeTo: this.route, + queryParams: { cpfp: this.cpfpMode ? 'simple' : null }, + queryParamsHandling: 'merge', + preserveFragment: true, + replaceUrl: true, + }); + } } - private updateCpfpMode(mode: 'advanced' | 'simple' | null) { - this.cpfpMode = mode; - this.router.navigate([], { - relativeTo: this.route, - queryParams: { cpfp: mode }, - queryParamsHandling: 'merge', - preserveFragment: true, - replaceUrl: true, - }); + private isCpfpParamEnabled(cpfpParam: string | undefined): boolean { + return cpfpParam === 'true' || cpfpParam === 'advanced' || cpfpParam === 'simple'; } toggleGraph() { diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts index 05671ff65..9fa98bc63 100644 --- a/frontend/src/app/shared/shared.module.ts +++ b/frontend/src/app/shared/shared.module.ts @@ -9,7 +9,7 @@ import { faFilter, faAngleDown, faAngleUp, faAngleRight, faAngleLeft, faBolt, fa faCircleCheck, faUserCircle, faCheck, faRocket, faScaleBalanced, faHourglassStart, faHourglassHalf, faHourglassEnd, faWandMagicSparkles, faTimeline, faCircleXmark, faCalendarCheck, faMoneyBillTrendUp, faRobot, faShareNodes, faCreditCard, faMicroscope, faExclamationTriangle, faLockOpen, faPaperclip, faAddressCard, faMedal, faBug, faFilePdf, faPiggyBank, faLayerGroup, faHeart, faCashRegister, faCodeFork, faCode, - faCalendar, faPause, faPlay} from '@fortawesome/free-solid-svg-icons'; + faCalendar, faPause, faPlay, faExpand, faCompress} from '@fortawesome/free-solid-svg-icons'; import { InfiniteScrollModule } from 'ngx-infinite-scroll'; import { MenuComponent } from '@components/menu/menu.component'; import { PreviewTitleComponent } from '@components/master-page-preview/preview-title.component'; @@ -498,5 +498,7 @@ export class SharedModule { library.addIcons(faCode); library.addIcons(faPause); library.addIcons(faPlay); + library.addIcons(faExpand); + library.addIcons(faCompress); } } From 4b64c4a3339e0deae5f26d5c20107dec6238f689 Mon Sep 17 00:00:00 2001 From: mononaut Date: Sun, 3 May 2026 08:45:52 +0000 Subject: [PATCH 04/17] improve interactivity & tooltips in cluster diagram --- .../cluster-diagram.component.html | 95 +++++++++++--- .../cluster-diagram.component.scss | 119 ++++++++++++++++-- .../cluster-diagram.component.ts | 88 +++++++++---- .../cluster-diagram/cluster-renderer.ts | 8 +- 4 files changed, 253 insertions(+), 57 deletions(-) diff --git a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.html b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.html index 359116577..59dbe36de 100644 --- a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.html +++ b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.html @@ -19,26 +19,50 @@ [attr.fill]="edge.childColor" [attr.fill-opacity]="edge.childInactive ? 0.45 : 1" /> - - + + + + + + + + [class.inactive]="outline.chunkIndex !== effectiveActiveChunk" + [attr.d]="outline.path" + [ngbTooltip]="chunkLabelTooltip" + container="body" + placement="top" + (mouseenter)="onChunkEnter(outline.chunkIndex)" + (mouseleave)="onChunkLeave()" /> + text-anchor="middle" + [ngbTooltip]="chunkLabelTooltip" + container="body" + placement="top" + (mouseenter)="onChunkEnter(outline.chunkIndex)" + (mouseleave)="onChunkLeave()"> {{ outline.feerate | feeRounding }} sat/vB @@ -50,13 +74,17 @@ fill="none" stroke="transparent" stroke-width="12" - (mouseenter)="onEdgeEnter(i)" + (mouseenter)="onEdgeEnter(i, $event)" + (mousemove)="onEdgeMove($event)" (mouseleave)="onEdgeLeave()" /> @@ -72,7 +100,8 @@ +
-
-

{{ hoverNode.tx.txid | shortenString }}

-

{{ hoverNode.tx.fee | number }} sat

-

-

{{ hoverNode.feerate | feeRounding }} sat/vB

+mempool chunk + +
+ +
+ {{ hoverNode.tx.txid | shortenString }} + this transaction +
+
+ + + + + + + + + + + + + +
Fee{{ hoverNode.tx.fee | number }} sats
Size
Fee rate{{ hoverNode.feerate | feeRounding }} sat/vB
+
+
parents
+
children
+
+
+
+
+
parent
+
child
diff --git a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss index 735ce0327..cb5bb8b1a 100644 --- a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss +++ b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss @@ -1,3 +1,11 @@ +:host { + position: relative; + display: block; + --cluster-ancestor-color: var(--info); + --cluster-descendant-color: var(--primary); + --cluster-direct-color: white; +} + .graph-container { position: relative; width: 100%; @@ -73,6 +81,30 @@ stroke-width: 2; transition: stroke 150ms; pointer-events: none; + + &.ancestor { + stroke: var(--cluster-ancestor-color); + } + + &.descendant { + stroke: var(--cluster-descendant-color); + } + + &.direct { + stroke: var(--cluster-direct-color); + } +} + +.edge-arrow-ancestor-path { + fill: var(--cluster-ancestor-color); +} + +.edge-arrow-descendant-path { + fill: var(--cluster-descendant-color); +} + +.edge-arrow-direct-path { + fill: var(--cluster-direct-color); } .node-group { @@ -89,15 +121,19 @@ transition: stroke 150ms; &.current { - stroke: var(--mainnet-alt); + stroke: var(--cluster-direct-color); } - &.related { - stroke: rgba(255, 255, 255, 0.6); + &.ancestor { + stroke: var(--cluster-ancestor-color); + } + + &.descendant { + stroke: var(--cluster-descendant-color); } &.hovered { - stroke: white; + stroke: var(--cluster-direct-color); } } @@ -114,13 +150,78 @@ border-radius: 4px; box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.5); color: var(--tooltip-grey); - padding: 10px 15px; + padding: 8px 12px; text-align: left; pointer-events: none; - max-width: 350px; + max-width: 360px; + white-space: nowrap; - p { - margin: 0; - white-space: nowrap; + .tx-id-row { + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 6px; + padding-bottom: 6px; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + } + + .this-tx-badge { + font-size: 0.75em; + background: rgba(255, 255, 255, 0.12); + color: white; + border-radius: 3px; + padding: 1px 6px; + } + + .tooltip-body { + display: flex; + align-items: center; + gap: 14px; + } + + table.stats { + border-collapse: collapse; + + th, td { + padding: 1px 0; + font-weight: normal; + vertical-align: baseline; + } + + th { + text-align: left; + padding-right: 10px; + opacity: 0.7; + } + + .unit { + opacity: 0.7; + font-size: 0.85em; + } + } + + .legend { + display: flex; + flex-direction: column; + gap: 4px; + font-size: 0.85em; + padding-left: 10px; + border-left: 1px solid rgba(255, 255, 255, 0.1); + + > div { + display: flex; + align-items: center; + gap: 5px; + } + } + + .swatch { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 2px; + + &.ancestor { background: var(--cluster-ancestor-color); } + &.descendant { background: var(--cluster-descendant-color); } } } diff --git a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.ts b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.ts index a4c71f79d..6b26c5301 100644 --- a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.ts +++ b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.ts @@ -38,6 +38,8 @@ export class ClusterDiagramComponent implements OnChanges, AfterViewInit, OnDest activeChunkIndex = 0; hoverNode: RenderedNode | null = null; + hoverEdge: RenderedEdge | null = null; + hoverChunkIndex: number | null = null; tooltipPosition = { x: 0, y: 0 }; readonly idPrefix = `cluster-${++nextClusterDiagramInstance}`; @@ -129,11 +131,13 @@ export class ClusterDiagramComponent implements OnChanges, AfterViewInit, OnDest node.hovered = true; for (const edge of this.edges) { if (edge.parentIndex === node.index) { - this.nodes[edge.childIndex].related = true; + this.nodes[edge.childIndex].relation = 'descendant'; edge.highlighted = true; + edge.highlightKind = 'descendant'; } else if (edge.childIndex === node.index) { - this.nodes[edge.parentIndex].related = true; + this.nodes[edge.parentIndex].relation = 'ancestor'; edge.highlighted = true; + edge.highlightKind = 'ancestor'; } } this.updateTooltipPosition(event); @@ -153,22 +157,61 @@ export class ClusterDiagramComponent implements OnChanges, AfterViewInit, OnDest this.cd.markForCheck(); } - onEdgeEnter(edgeIndex: number): void { + onEdgeEnter(edgeIndex: number, event: MouseEvent): void { if (this.preview) { return; } this.clearHighlights(); const edge = this.edges[edgeIndex]; edge.highlighted = true; - this.nodes[edge.parentIndex].related = true; - this.nodes[edge.childIndex].related = true; + edge.highlightKind = 'direct'; + this.nodes[edge.parentIndex].relation = 'ancestor'; + this.nodes[edge.childIndex].relation = 'descendant'; + this.hoverEdge = edge; + this.updateTooltipPosition(event); + this.cd.markForCheck(); + } + + onEdgeMove(event: MouseEvent): void { + if (this.preview) { return; } + this.updateTooltipPosition(event); this.cd.markForCheck(); } onEdgeLeave(): void { if (this.preview) { return; } + this.hoverEdge = null; this.clearHighlights(); this.cd.markForCheck(); } + onChunkEnter(chunkIndex: number): void { + if (this.preview) { return; } + this.hoverChunkIndex = chunkIndex; + this.applyEffectiveChunk(); + this.cd.markForCheck(); + } + + onChunkLeave(): void { + if (this.preview) { return; } + this.hoverChunkIndex = null; + this.applyEffectiveChunk(); + this.cd.markForCheck(); + } + + get effectiveActiveChunk(): number { + return this.hoverChunkIndex ?? this.activeChunkIndex; + } + + private applyEffectiveChunk(): void { + const effective = this.effectiveActiveChunk; + for (const node of this.nodes) { + node.inactive = node.chunkIndex !== effective; + } + for (const edge of this.edges) { + edge.parentInactive = this.nodes[edge.parentIndex].chunkIndex !== effective; + edge.childInactive = this.nodes[edge.childIndex].chunkIndex !== effective; + } + } + onNodeClick(node: RenderedNode): void { if (this.preview) { return; } const network = this.stateService.network; @@ -179,41 +222,32 @@ export class ClusterDiagramComponent implements OnChanges, AfterViewInit, OnDest private clearHighlights(): void { for (const node of this.nodes) { node.hovered = false; - node.related = false; + node.relation = null; } for (const edge of this.edges) { edge.highlighted = false; + edge.highlightKind = null; } } private updateTooltipPosition(event: MouseEvent): void { if (!this.graphContainer) { return; } + if (!this.hoverNode && !this.hoverEdge) { return; } const container = this.graphContainer.nativeElement; const rect = container.getBoundingClientRect(); - let x = event.clientX - rect.left + container.scrollLeft + 15; - let y = event.clientY - rect.top + container.scrollTop + 15; - + const pointerX = event.clientX - rect.left; + const pad = 0; + let tipW = 0; if (this.tooltipElement) { - const tipRect = this.tooltipElement.nativeElement.getBoundingClientRect(); - const visibleLeft = container.scrollLeft; - const visibleRight = visibleLeft + rect.width; - const visibleTop = container.scrollTop; - const visibleBottom = visibleTop + rect.height; - - if (x + tipRect.width > visibleRight) { - x = Math.max(visibleLeft, visibleRight - tipRect.width - 10); - } - if (x < visibleLeft) { - x = visibleLeft; - } - if (y + tipRect.height > visibleBottom) { - y = y - tipRect.height - 30; - } - if (y < visibleTop) { - y = visibleTop; - } + tipW = this.tooltipElement.nativeElement.getBoundingClientRect().width; } + const visibleW = rect.width; + + const onLeftHalf = pointerX < visibleW / 2; + const x = onLeftHalf ? visibleW - tipW - pad : pad; + const y = pad; + this.tooltipPosition = { x, y }; } diff --git a/frontend/src/app/components/cluster-diagram/cluster-renderer.ts b/frontend/src/app/components/cluster-diagram/cluster-renderer.ts index 7bc3ab356..826211293 100644 --- a/frontend/src/app/components/cluster-diagram/cluster-renderer.ts +++ b/frontend/src/app/components/cluster-diagram/cluster-renderer.ts @@ -1,5 +1,7 @@ import { GridLayout, GridNode, GridEdge, ChunkRegion, cellKey, cellCol, cellRow } from './cluster-layout'; +export type RelatedKind = null | 'ancestor' | 'descendant' | 'direct'; + export interface RenderedNode { index: number; tx: { txid: string; fee: number; weight: number }; @@ -16,7 +18,7 @@ export interface RenderedNode { inactive: boolean; isCurrent: boolean; hovered: boolean; - related: boolean; + relation: RelatedKind; visible: boolean; } @@ -35,6 +37,7 @@ export interface RenderedEdge { x2: number; y2: number; highlighted: boolean; + highlightKind: RelatedKind; visible: boolean; } @@ -304,7 +307,7 @@ function renderNodes(gridNodes: GridNode[], params: RenderParams, geo: GridGeome inactive, isCurrent: params.txids[gn.index] === params.currentTxid, hovered: false, - related: false, + relation: null, visible, }; }); @@ -406,6 +409,7 @@ function renderEdges( x1: first.x, y1: first.y, x2: last.x, y2: last.y, highlighted: false, + highlightKind: null, visible: pNode.visible && cNode.visible, }; }); From b6d2b745e8910b64779370b3472129d706c58917 Mon Sep 17 00:00:00 2001 From: mononaut Date: Sun, 3 May 2026 08:49:27 +0000 Subject: [PATCH 05/17] tweak cluster diagram algorithm --- .../cluster-diagram/cluster-layout.ts | 162 +++++++++++++++--- .../cluster-diagram/cluster-renderer.ts | 102 +++++++++-- 2 files changed, 221 insertions(+), 43 deletions(-) diff --git a/frontend/src/app/components/cluster-diagram/cluster-layout.ts b/frontend/src/app/components/cluster-diagram/cluster-layout.ts index c9d0e2c38..ffc5ea996 100644 --- a/frontend/src/app/components/cluster-diagram/cluster-layout.ts +++ b/frontend/src/app/components/cluster-diagram/cluster-layout.ts @@ -140,6 +140,18 @@ function assignRows( ): Int32Array { const rows = new Int32Array(n); const placed = new Uint8Array(n); + const nodeCol = new Int32Array(n); + for (let c = 0; c < colNodes.length; c++) { + for (const i of colNodes[c]) { nodeCol[i] = c; } + } + + const nearestDescendantCol = new Int32Array(n); + nearestDescendantCol.fill(maxCol + 1); + for (let i = n - 1; i >= 0; i--) { + for (const ch of children[i]) { + nearestDescendantCol[i] = Math.min(nearestDescendantCol[i], nodeCol[ch], nearestDescendantCol[ch]); + } + } for (let c = maxCol; c >= 0; c--) { const layer = colNodes[c]; @@ -160,14 +172,24 @@ function assignRows( return (totalRows - 1) / 2; }); - const sorted = layer.map((nodeIdx, arrIdx) => ({ nodeIdx, arrIdx, target: targets[arrIdx], chunk: txChunk[nodeIdx] })); + const sorted = layer.map((nodeIdx, arrIdx) => ({ + nodeIdx, arrIdx, target: targets[arrIdx], chunk: txChunk[nodeIdx], nearestDescendantCol: nearestDescendantCol[nodeIdx], + })); sorted.sort((a, b) => { const dt = a.target - b.target; if (Math.abs(dt) > 0.001) { return dt; } - return a.chunk - b.chunk; + if (a.chunk !== b.chunk) { return a.chunk - b.chunk; } + if (a.nearestDescendantCol !== b.nearestDescendantCol) { + return a.nearestDescendantCol - b.nearestDescendantCol; + } + return a.nodeIdx - b.nodeIdx; }); - const slots = pickSlots(sorted.map(s => s.target), totalRows); + const slots = pickSlots( + sorted.map(s => s.target), + totalRows, + hasDescendantColumnTie(sorted.map(s => s.nodeIdx), sorted.map(s => s.target), nearestDescendantCol, maxCol), + ); for (let k = 0; k < sorted.length; k++) { rows[sorted[k].nodeIdx] = slots[k]; placed[sorted[k].nodeIdx] = 1; @@ -178,7 +200,7 @@ function assignRows( const forward = pass % 2 === 0; for (let c = forward ? 0 : maxCol; forward ? c <= maxCol : c >= 0; forward ? c++ : c--) { const layer = colNodes[c]; - if (layer.length <= 1) { continue; } + if (layer.length === 0) { continue; } const targets = layer.map(i => { const neighbors = forward ? txs[i].parents : children[i]; @@ -189,11 +211,22 @@ function assignRows( }); const indexed = layer.map((_, idx) => idx); - indexed.sort((a, b) => targets[a] - targets[b]); + indexed.sort((a, b) => { + const dt = targets[a] - targets[b]; + if (Math.abs(dt) > 0.001) { return dt; } + if (nearestDescendantCol[layer[a]] !== nearestDescendantCol[layer[b]]) { + return nearestDescendantCol[layer[a]] - nearestDescendantCol[layer[b]]; + } + return layer[a] - layer[b]; + }); - const currentSlots = layer.map(i => rows[i]).sort((a, b) => a - b); + const slots = pickSlots( + indexed.map(i => targets[i]), + totalRows, + hasDescendantColumnTie(indexed.map(i => layer[i]), indexed.map(i => targets[i]), nearestDescendantCol, maxCol), + ); for (let k = 0; k < indexed.length; k++) { - rows[layer[indexed[k]]] = currentSlots[k]; + rows[layer[indexed[k]]] = slots[k]; } } } @@ -203,9 +236,30 @@ function assignRows( return rows; } -function pickSlots(targets: number[], totalRows: number): number[] { +function hasDescendantColumnTie( + nodes: number[], + targets: number[], + nearestDescendantCol: Int32Array, + maxCol: number, +): boolean { + for (let i = 0; i < nodes.length; i++) { + if (nearestDescendantCol[nodes[i]] > maxCol) { continue; } + for (let j = 0; j < nodes.length; j++) { + if ( + i !== j + && nearestDescendantCol[nodes[i]] !== nearestDescendantCol[nodes[j]] + && Math.abs(targets[i] - targets[j]) < 0.001 + ) { + return true; + } + } + } + return false; +} + +function pickSlots(targets: number[], totalRows: number, packFullLayer = false): number[] { const count = targets.length; - if (count >= totalRows) { + if (count >= totalRows && !packFullLayer) { return targets.map((_, i) => i); } @@ -278,25 +332,50 @@ function computeWaypoints( return waypoints; } + const lo = -1; + const hi = maxRow + 1; for (let c = pNode.col + 1; c < cNode.col; c++) { const frac = (c - pNode.col) / (cNode.col - pNode.col); const idealRow = pNode.row + frac * (cNode.row - pNode.row); - let bestRow = Math.max(0, Math.min(maxRow, Math.round(idealRow))); + const targetRow = Math.max(lo, Math.min(hi, Math.round(idealRow))); - if (nodeAt.has(cellKey(c, bestRow))) { - for (let dr = 1; dr <= maxRow; dr++) { - if (bestRow + dr <= maxRow && !nodeAt.has(cellKey(c, bestRow + dr))) { bestRow = bestRow + dr; break; } - if (bestRow - dr >= 0 && !nodeAt.has(cellKey(c, bestRow - dr))) { bestRow = bestRow - dr; break; } - } - } - - waypoints.push({ col: c, row: bestRow }); + waypoints.push({ + col: c, + row: selectOpenWaypointRow(c, targetRow, idealRow, nodeAt, lo, hi), + }); } waypoints.push({ col: cNode.col, row: cNode.row }); return waypoints; } +function selectOpenWaypointRow( + col: number, + targetRow: number, + idealRow: number, + nodeAt: Map, + lo: number, + hi: number, +): number { + if (!nodeAt.has(cellKey(col, targetRow))) { + return targetRow; + } + + const preferDown = idealRow > targetRow; + for (let dr = 1; dr <= hi - lo; dr++) { + const first = preferDown ? targetRow + dr : targetRow - dr; + const second = preferDown ? targetRow - dr : targetRow + dr; + if (first >= lo && first <= hi && !nodeAt.has(cellKey(col, first))) { + return first; + } + if (second >= lo && second <= hi && !nodeAt.has(cellKey(col, second))) { + return second; + } + } + + return targetRow; +} + interface VSeg { edgeIdx: number; segIdx: number; @@ -775,7 +854,11 @@ function assignHorizontalLanes(edges: GridEdge[], rowLaneCounts: number[]): void edgeSegments.sort((a, b) => a.col - b.col); let start = 0; for (let i = 1; i <= edgeSegments.length; i++) { - if (i === edgeSegments.length || edgeSegments[i].col !== edgeSegments[i - 1].col + 1) { + const prev = edgeSegments[i - 1]; + const curr = edgeSegments[i]; + const contiguous = curr && curr.col === prev.col + 1 + && !(prev.type === 'approach' && curr.type === 'approach'); + if (i === edgeSegments.length || !contiguous) { const spanSegs = edgeSegments.slice(start, i); const colOrders = new Map(); for (const s of spanSegs) { if (s.type !== 'approach') { colOrders.set(s.col, s.order); } } @@ -907,9 +990,34 @@ function assignLanes( for (let i = 0; i < n; i++) { lane[i] = Math.floor((minLane[i] + totalLanes - 1 - distToSink[i]) / 2); } + separateOverlappingLanes(lines, lane, compare); return lane; } +function separateOverlappingLanes( + lines: { minPos: number; maxPos: number }[], + lane: number[], + compare: (i: number, j: number) => number, +): void { + for (let pass = 0; pass < lines.length * lines.length; pass++) { + let changed = false; + + for (let i = 0; i < lines.length; i++) { + for (let j = i + 1; j < lines.length; j++) { + const lo = Math.max(lines[i].minPos, lines[j].minPos); + const hi = Math.min(lines[i].maxPos, lines[j].maxPos); + if (lo >= hi || lane[i] !== lane[j]) { continue; } + + const cmp = compare(i, j); + lane[cmp > 0 ? i : j]++; + changed = true; + } + } + + if (!changed) { return; } + } +} + function clusterOverlapping(items: T[]): T[][] { const clusters: T[][] = []; @@ -1049,19 +1157,17 @@ function computeAlternativeWaypoints( ): { col: number; row: number }[] { const waypoints: { col: number; row: number }[] = [{ col: pNode.col, row: pNode.row }]; + const lo = -1; + const hi = maxRow + 1; for (let c = pNode.col + 1; c < cNode.col; c++) { const frac = (c - pNode.col) / (cNode.col - pNode.col); const idealRow = pNode.row + frac * (cNode.row - pNode.row); - let targetRow = Math.max(0, Math.min(maxRow, Math.round(idealRow) + offset)); + const targetRow = Math.max(lo, Math.min(hi, Math.round(idealRow) + offset)); - if (nodeAt.has(cellKey(c, targetRow))) { - for (let dr = 1; dr <= maxRow; dr++) { - if (targetRow + dr <= maxRow && !nodeAt.has(cellKey(c, targetRow + dr))) { targetRow = targetRow + dr; break; } - if (targetRow - dr >= 0 && !nodeAt.has(cellKey(c, targetRow - dr))) { targetRow = targetRow - dr; break; } - } - } - - waypoints.push({ col: c, row: targetRow }); + waypoints.push({ + col: c, + row: selectOpenWaypointRow(c, targetRow, idealRow, nodeAt, lo, hi), + }); } waypoints.push({ col: cNode.col, row: cNode.row }); diff --git a/frontend/src/app/components/cluster-diagram/cluster-renderer.ts b/frontend/src/app/components/cluster-diagram/cluster-renderer.ts index 826211293..69f30d580 100644 --- a/frontend/src/app/components/cluster-diagram/cluster-renderer.ts +++ b/frontend/src/app/components/cluster-diagram/cluster-renderer.ts @@ -91,6 +91,8 @@ interface GridGeometry { cellW: number; totalCols: number; totalRows: number; + virtualTopY: number; + virtualBottomY: number; dim: RenderDimensions; } @@ -141,10 +143,26 @@ export function renderLayout(layout: GridLayout, params: RenderParams): RenderRe } } - const rowTopY: number[] = [dim.marginY]; + let needsVirtualTop = false; + let needsVirtualBottom = false; + for (const e of layout.edges) { + for (const wp of e.waypoints) { + if (wp.row < 0) { needsVirtualTop = true; } + if (wp.row >= layout.rows) { needsVirtualBottom = true; } + } + } + const virtualGap = dim.laneSpacing * 3; + const topPad = needsVirtualTop ? virtualGap : 0; + const bottomPad = needsVirtualBottom ? virtualGap : 0; + + const rowTopY: number[] = [dim.marginY + topPad]; for (let r = 1; r < layout.rows; r++) { rowTopY.push(rowTopY[r - 1] + rowHeights[r - 1]); } + const virtualTopY = needsVirtualTop ? dim.marginY + topPad / 2 : dim.marginY; + const virtualBottomY = layout.rows > 0 + ? rowTopY[layout.rows - 1] + rowHeights[layout.rows - 1] + bottomPad / 2 + : dim.marginY; const gutterWidths: number[] = []; for (let c = 0; c < layout.cols - 1; c++) { @@ -174,6 +192,7 @@ export function renderLayout(layout: GridLayout, params: RenderParams): RenderRe const geo: GridGeometry = { colLeftX, rowTopY, rowHeights, gutterWidths, cellW, totalCols: layout.cols, totalRows: layout.rows, + virtualTopY, virtualBottomY, dim, }; @@ -182,7 +201,7 @@ export function renderLayout(layout: GridLayout, params: RenderParams): RenderRe const chunkOutlines = params.preview ? [] : renderChunkOutlines(layout.chunks, params, geo); const fullWidth = dim.marginX * 2 + layout.cols * cellW + totalGutterW; - const fullHeight = rowTopY[layout.rows - 1] + rowHeights[layout.rows - 1] + dim.marginY; + const fullHeight = rowTopY[layout.rows - 1] + rowHeights[layout.rows - 1] + bottomPad + dim.marginY; if (params.preview) { const selected = nodes.find(n => n.isCurrent && n.visible) ?? nodes.find(n => n.visible); @@ -241,7 +260,8 @@ function geoCellX(geo: GridGeometry, col: number): number { } function geoCellY(geo: GridGeometry, row: number): number { - if (row < 0 || row >= geo.totalRows) { return geo.dim.marginY; } + if (row < 0) { return geo.virtualTopY; } + if (row >= geo.totalRows) { return geo.virtualBottomY; } return geo.rowTopY[row] + geo.rowHeights[row] / 2; } @@ -254,7 +274,8 @@ function geoCellLeft(geo: GridGeometry, col: number): number { } function geoCellTop(geo: GridGeometry, row: number): number { - if (row < 0 || row >= geo.totalRows) { return geo.dim.marginY; } + if (row < 0) { return geo.virtualTopY; } + if (row >= geo.totalRows) { return geo.virtualBottomY; } return geo.rowTopY[row]; } @@ -263,19 +284,24 @@ function geoCellRight(geo: GridGeometry, col: number): number { } function geoCellBottom(geo: GridGeometry, row: number): number { - if (row < 0 || row >= geo.totalRows) { return geo.dim.marginY; } + if (row < 0) { return geo.virtualTopY; } + if (row >= geo.totalRows) { return geo.virtualBottomY; } return geo.rowTopY[row] + geo.rowHeights[row]; } -function borderX(geo: GridGeometry, b: number): number { +function borderX(geo: GridGeometry, b: number, side: 'left' | 'right' | null = null): number { if (b <= 0) { return geoCellLeft(geo, 0) - OUTLINE_PAD; } if (b >= geo.totalCols) { return geoCellRight(geo, geo.totalCols - 1) + OUTLINE_PAD; } + if (side === 'left') { return geoCellLeft(geo, b) - geo.dim.laneSpacing / 2; } + if (side === 'right') { return geoCellRight(geo, b - 1) + geo.dim.laneSpacing / 2; } return (geoCellRight(geo, b - 1) + geoCellLeft(geo, b)) / 2; } -function borderY(geo: GridGeometry, b: number): number { +function borderY(geo: GridGeometry, b: number, side: 'top' | 'bottom' | null = null): number { if (b <= 0) { return geoCellTop(geo, 0) - OUTLINE_PAD; } if (b >= geo.totalRows) { return geoCellBottom(geo, geo.totalRows - 1) + OUTLINE_PAD; } + if (side === 'top') { return geoCellTop(geo, b) + geo.dim.laneSpacing / 2; } + if (side === 'bottom') { return geoCellBottom(geo, b - 1) - geo.dim.laneSpacing / 2; } return (geoCellBottom(geo, b - 1) + geoCellTop(geo, b)) / 2; } @@ -554,7 +580,7 @@ function renderChunkOutlines( const ty = borderY(geo, r); if (ty < labelY || (ty === labelY && cx < labelX)) { labelX = cx; - labelY = ty - 4; + labelY = ty - 8; } } @@ -578,10 +604,16 @@ function collectBoundarySegments(chunk: ChunkRegion, geo: GridGeometry): Segment for (const cell of chunk.cells) { const c = cellCol(cell), r = cellRow(cell); - const left = borderX(geo, c); - const right = borderX(geo, c + 1); - const top = borderY(geo, r); - const bottom = borderY(geo, r + 1); + const left = cornerX(chunk, geo, c, r); + const right = cornerX(chunk, geo, c + 1, r); + const bottomLeft = cornerX(chunk, geo, c, r + 1); + const bottomRight = cornerX(chunk, geo, c + 1, r + 1); + const top = borderY(geo, r, 'top'); + const bottom = borderY(geo, r + 1, 'bottom'); + const leftTop = cornerY(chunk, geo, c, r); + const leftBottom = cornerY(chunk, geo, c, r + 1); + const rightTop = cornerY(chunk, geo, c + 1, r); + const rightBottom = cornerY(chunk, geo, c + 1, r + 1); const hasAbove = chunk.cells.has(cellKey(c, r - 1)); const hasBelow = chunk.cells.has(cellKey(c, r + 1)); @@ -589,14 +621,54 @@ function collectBoundarySegments(chunk: ChunkRegion, geo: GridGeometry): Segment const hasRight = chunk.cells.has(cellKey(c + 1, r)); if (!hasAbove) { segments.push({ x1: left, y1: top, x2: right, y2: top }); } - if (!hasBelow) { segments.push({ x1: right, y1: bottom, x2: left, y2: bottom }); } - if (!hasLeft) { segments.push({ x1: left, y1: bottom, x2: left, y2: top }); } - if (!hasRight) { segments.push({ x1: right, y1: top, x2: right, y2: bottom }); } + if (!hasBelow) { segments.push({ x1: bottomRight, y1: bottom, x2: bottomLeft, y2: bottom }); } + if (!hasLeft) { + const x = borderX(geo, c, 'left'); + segments.push({ x1: x, y1: leftBottom, x2: x, y2: leftTop }); + } + if (!hasRight) { + const x = borderX(geo, c + 1, 'right'); + segments.push({ x1: x, y1: rightTop, x2: x, y2: rightBottom }); + } } return segments; } +function cornerX(chunk: ChunkRegion, geo: GridGeometry, col: number, row: number): number { + const side = verticalBoundarySide( + chunk.cells.has(cellKey(col - 1, row)), + chunk.cells.has(cellKey(col, row)), + ) || verticalBoundarySide( + chunk.cells.has(cellKey(col - 1, row - 1)), + chunk.cells.has(cellKey(col, row - 1)), + ); + return borderX(geo, col, side); +} + +function verticalBoundarySide(leftOccupied: boolean, rightOccupied: boolean): 'left' | 'right' | null { + if (!leftOccupied && rightOccupied) { return 'left'; } + if (leftOccupied && !rightOccupied) { return 'right'; } + return null; +} + +function cornerY(chunk: ChunkRegion, geo: GridGeometry, col: number, row: number): number { + const side = horizontalBoundarySide( + chunk.cells.has(cellKey(col, row - 1)), + chunk.cells.has(cellKey(col, row)), + ) || horizontalBoundarySide( + chunk.cells.has(cellKey(col - 1, row - 1)), + chunk.cells.has(cellKey(col - 1, row)), + ); + return borderY(geo, row, side); +} + +function horizontalBoundarySide(aboveOccupied: boolean, belowOccupied: boolean): 'top' | 'bottom' | null { + if (!aboveOccupied && belowOccupied) { return 'top'; } + if (aboveOccupied && !belowOccupied) { return 'bottom'; } + return null; +} + function endpointKey(x: number, y: number): string { return `${Math.round(x)}:${Math.round(y)}`; } From 6be3fe685f504930cb1f2e87c20e7cc90cc54e9a Mon Sep 17 00:00:00 2001 From: mononaut Date: Mon, 4 May 2026 11:20:35 +0000 Subject: [PATCH 06/17] fix cluster preview responsiveness --- .../cluster-diagram.component.scss | 4 +- .../transaction-details.component.html | 46 ++++++++++------ .../transaction-details.component.scss | 55 +++++++++++++++---- 3 files changed, 74 insertions(+), 31 deletions(-) diff --git a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss index cb5bb8b1a..603a5f999 100644 --- a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss +++ b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.scss @@ -23,10 +23,10 @@ overflow: hidden; pointer-events: none; border-radius: 4px; - background-color: var(--cluster-preview-background, var(--stat-box-bg)); + background-color: transparent; box-shadow: var(--cluster-preview-shadow, none); cursor: var(--cluster-preview-cursor, default); - transition: box-shadow 150ms ease, background-color 150ms ease; + transition: box-shadow 150ms ease; svg { display: block; diff --git a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html index 2c8c2eb82..b52987fe3 100644 --- a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html +++ b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html @@ -245,6 +245,24 @@ @if (!isLoadingTx) { @if ((cpfpInfo && hasEffectiveFeeRate) || (accelerationInfo && isAcceleration)) { + +
+ + +
+ +

This transaction belongs to a chunk of {{ clusterPreviewStats.chunkSize }} transaction{{ clusterPreviewStats.chunkSize === 1 ? '' : 's' }}, with combined effective fee rate {{ clusterPreviewStats.chunkFeerate | feeRounding }} sat/vB.

+

In a mempool cluster containing {{ clusterPreviewStats.otherChunks }} other chunk{{ clusterPreviewStats.otherChunks === 1 ? '' : 's' }}.

+

Click for more details.

+
+
@if (isAcceleration) { Accelerated fee rate @@ -252,7 +270,7 @@ Effective fee rate } -
+
@if (accelerationInfo?.acceleratedFeeRate && (!tx.effectiveFeePerVsize || accelerationInfo.acceleratedFeeRate >= tx.effectiveFeePerVsize || tx.acceleration)) { @@ -265,28 +283,20 @@ }
@if (cpfpInfo?.cluster && tx?.txid) { -
- - -
- -

This transaction belongs to a chunk of {{ clusterPreviewStats.chunkSize }} transaction{{ clusterPreviewStats.chunkSize === 1 ? '' : 's' }}, with combined effective fee rate {{ clusterPreviewStats.chunkFeerate | feeRounding }} sat/vB.

-

In a mempool cluster containing {{ clusterPreviewStats.otherChunks }} other chunk{{ clusterPreviewStats.otherChunks === 1 ? '' : 's' }}.

-

Click for more details.

-
+ } @else if (hasCpfp) { - + }
+ @if (cpfpInfo?.cluster && tx?.txid) { + + + + + + } } } @else { diff --git a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss index 06f9cb602..3623c4a31 100644 --- a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss +++ b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.scss @@ -166,25 +166,27 @@ } .effective-fee-row { - display: flex; - align-items: center; - gap: 0.5rem; - flex-wrap: wrap; + &.has-cluster-preview { + display: flex; + align-items: center; + gap: 0.5rem; + flex-wrap: wrap; - .effective-fee-container { - flex: 0 0 auto; + .effective-fee-container { + flex: 0 0 auto; + } } } .cluster-preview-inline { position: relative; - flex: 1 1 80px; - min-width: 80px; - max-width: 100%; + flex: 1 1 120px; + min-width: 120px; + max-width: 300px; display: flex; align-items: center; overflow: visible; - margin: -0.75rem -0.75rem -0.75rem 0; + margin: -0.75rem -0.75rem -0.75rem auto; cursor: pointer; .cluster-preview-diagram { @@ -214,11 +216,42 @@ &:hover .cluster-preview-diagram, &:focus-visible .cluster-preview-diagram { - --cluster-preview-background: color-mix(in srgb, var(--info) 8%, var(--stat-box-bg)); --cluster-preview-shadow: 0 0 0 1px var(--info), 0 0 8px color-mix(in srgb, var(--info) 35%, transparent); } } +.cluster-preview-table-row { + display: none; +} + +@media (max-width: 849.98px) and (min-width: 500px) { + .cluster-preview-inline { + order: -1; + margin-right: 0; + } +} + +@media (max-width: 499.98px) { + .effective-fee-row.has-cluster-preview .cluster-preview-inline { + display: none; + } + + .cluster-preview-table-row { + display: table-row; + + td { + padding-top: 0; + } + + .cluster-preview-inline { + width: 100%; + flex-basis: 100%; + max-width: 100%; + margin: -0.25rem 0 -0.75rem; + } + } +} + ::ng-deep .cluster-preview-ngb-tooltip .tooltip-inner { text-align: left; max-width: 320px; From a4ea01dcfc244c652d8c4559ab01e517671667d9 Mon Sep 17 00:00:00 2001 From: mononaut Date: Mon, 4 May 2026 11:35:14 +0000 Subject: [PATCH 07/17] disable cluster view for accelerated txs --- .../transaction-details/transaction-details.component.html | 6 +++--- .../app/components/transaction/transaction.component.html | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html index b52987fe3..d1019bc4a 100644 --- a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html +++ b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html @@ -270,7 +270,7 @@ Effective fee rate } -
+
@if (accelerationInfo?.acceleratedFeeRate && (!tx.effectiveFeePerVsize || accelerationInfo.acceleratedFeeRate >= tx.effectiveFeePerVsize || tx.acceleration)) { @@ -282,7 +282,7 @@ }
- @if (cpfpInfo?.cluster && tx?.txid) { + @if (cpfpInfo?.cluster && tx?.txid && !isAcceleration) { } @else if (hasCpfp) { @@ -290,7 +290,7 @@
- @if (cpfpInfo?.cluster && tx?.txid) { + @if (cpfpInfo?.cluster && tx?.txid && !isAcceleration) { diff --git a/frontend/src/app/components/transaction/transaction.component.html b/frontend/src/app/components/transaction/transaction.component.html index d9f6d4be8..bc9145759 100644 --- a/frontend/src/app/components/transaction/transaction.component.html +++ b/frontend/src/app/components/transaction/transaction.component.html @@ -85,12 +85,12 @@
-

Cluster

-

Related Transactions

+

Cluster

+

Related Transactions

- +
From 2644a451837ae4dffa657e193000085daf68d83c Mon Sep 17 00:00:00 2001 From: mononaut Date: Mon, 4 May 2026 12:10:31 +0000 Subject: [PATCH 08/17] cluster preview - address copilot comments --- .../cluster-diagram/cluster-diagram.component.ts | 12 +++++++----- .../transaction-details.component.html | 12 ++++++++++-- .../transaction/transaction-raw.component.ts | 8 ++++++-- .../transaction/transaction.component.ts | 16 +++++++++++++++- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.ts b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.ts index 6b26c5301..df14efcba 100644 --- a/frontend/src/app/components/cluster-diagram/cluster-diagram.component.ts +++ b/frontend/src/app/components/cluster-diagram/cluster-diagram.component.ts @@ -237,12 +237,14 @@ export class ClusterDiagramComponent implements OnChanges, AfterViewInit, OnDest const rect = container.getBoundingClientRect(); const pointerX = event.clientX - rect.left; const pad = 0; - let tipW = 0; - if (this.tooltipElement) { - tipW = this.tooltipElement.nativeElement.getBoundingClientRect().width; - } - const visibleW = rect.width; + let tipW = Math.min(360, visibleW); + if (this.tooltipElement) { + const measuredW = this.tooltipElement.nativeElement.getBoundingClientRect().width; + if (measuredW > 0) { + tipW = Math.min(measuredW, visibleW); + } + } const onLeftHalf = pointerX < visibleW / 2; const x = onLeftHalf ? visibleW - tipW - pad : pad; diff --git a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html index d1019bc4a..cf60994f8 100644 --- a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html +++ b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html @@ -258,8 +258,16 @@
-

This transaction belongs to a chunk of {{ clusterPreviewStats.chunkSize }} transaction{{ clusterPreviewStats.chunkSize === 1 ? '' : 's' }}, with combined effective fee rate {{ clusterPreviewStats.chunkFeerate | feeRounding }} sat/vB.

-

In a mempool cluster containing {{ clusterPreviewStats.otherChunks }} other chunk{{ clusterPreviewStats.otherChunks === 1 ? '' : 's' }}.

+ @if (clusterPreviewStats.chunkSize === 1) { +

This transaction belongs to a chunk of 1 transaction, with combined effective fee rate {{ clusterPreviewStats.chunkFeerate | feeRounding }} sat/vB.

+ } @else { +

This transaction belongs to a chunk of {{ clusterPreviewStats.chunkSize }} transactions, with combined effective fee rate {{ clusterPreviewStats.chunkFeerate | feeRounding }} sat/vB.

+ } + @if (clusterPreviewStats.otherChunks === 1) { +

In a mempool cluster containing 1 other chunk.

+ } @else if (clusterPreviewStats.otherChunks > 1) { +

In a mempool cluster containing {{ clusterPreviewStats.otherChunks }} other chunks.

+ }

Click for more details.

diff --git a/frontend/src/app/components/transaction/transaction-raw.component.ts b/frontend/src/app/components/transaction/transaction-raw.component.ts index 8df3b5136..625cbf605 100644 --- a/frontend/src/app/components/transaction/transaction-raw.component.ts +++ b/frontend/src/app/components/transaction/transaction-raw.component.ts @@ -90,7 +90,7 @@ export class TransactionRawComponent implements OnInit, OnDestroy { this.seoService.setTitle($localize`:@@d7f92e6fe26fba6fff568cbdae5db4a5c8c6a55c:Preview Transaction`); this.seoService.setDescription($localize`:@@meta.description.preview-tx:Preview a transaction to the Bitcoin${seoDescriptionNetwork(this.stateService.network)} network using the transaction's raw hex data.`); this.websocketService.want(['blocks', 'mempool-blocks']); - this.cpfpMode = this.route.snapshot.queryParams['cpfp'] === 'true'; + this.cpfpMode = this.isCpfpParamEnabled(this.route.snapshot.queryParams['cpfp']); this.pushTxForm = this.formBuilder.group({ txRaw: ['', Validators.required], }); @@ -335,7 +335,7 @@ export class TransactionRawComponent implements OnInit, OnDestroy { this.isLoadingCpfpInfo = false; this.isLoadingBroadcast = false; this.adjustedVsize = null; - this.cpfpMode = null; + this.cpfpMode = false; this.hasCpfp = false; this.fetchCpfp = false; this.cpfpInfo = null; @@ -380,6 +380,10 @@ export class TransactionRawComponent implements OnInit, OnDestroy { } } + private isCpfpParamEnabled(cpfpParam: string | undefined): boolean { + return cpfpParam === 'true' || cpfpParam === 'advanced' || cpfpParam === 'simple'; + } + setupGraph() { this.maxInOut = Math.min(this.inOutLimit, Math.max(this.transaction?.vin?.length || 1, this.transaction?.vout?.length + 1 || 1)); this.graphHeight = this.graphExpanded ? this.maxInOut * 15 : Math.min(360, this.maxInOut * 80); diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts index 360cbcfe4..7db51e983 100644 --- a/frontend/src/app/components/transaction/transaction.component.ts +++ b/frontend/src/app/components/transaction/transaction.component.ts @@ -1133,7 +1133,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { relativeTo: this.route, queryParams: { cpfp: this.cpfpMode ? 'true' : null }, queryParamsHandling: 'merge', - fragment: this.cpfpMode ? 'cluster' : undefined, + fragment: this.getCpfpFragment(), replaceUrl: true, }); } else { @@ -1151,6 +1151,20 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { return cpfpParam === 'true' || cpfpParam === 'advanced' || cpfpParam === 'simple'; } + private getCpfpFragment(): string | null { + const currentParams = new URLSearchParams(this.fragmentParams?.toString() || this.route.snapshot.fragment || ''); + const fragmentParams = new URLSearchParams(); + if (this.cpfpMode) { + fragmentParams.set('cluster', ''); + } + for (const [key, value] of currentParams.entries()) { + if (key !== 'cluster') { + fragmentParams.set(key, value); + } + } + return fragmentParams.toString() || null; + } + toggleGraph() { const showFlow = !this.flowEnabled; this.stateService.hideFlow.next(!showFlow); From 3d923192c17096251f8b3c4fae4b35d4b909bd86 Mon Sep 17 00:00:00 2001 From: nymkappa Date: Thu, 7 May 2026 19:06:58 +0200 Subject: [PATCH 09/17] [accelerator] add stats documentation --- .../acceleration-stats.component.ts | 2 + .../src/app/docs/api-docs/api-docs-data.ts | 73 +++++++++++++++++-- .../src/app/interfaces/node-api.interface.ts | 4 +- 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.ts b/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.ts index 379152197..fad1bc7b9 100644 --- a/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.ts +++ b/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.ts @@ -4,6 +4,8 @@ import { ServicesApiServices } from '@app/services/services-api.service'; export type AccelerationStats = { totalRequested: number; + totalAccepted: number; + totalCompleted: number; totalBidBoost: number; totalVsize: number; } diff --git a/frontend/src/app/docs/api-docs/api-docs-data.ts b/frontend/src/app/docs/api-docs/api-docs-data.ts index 28ec714b1..69ca6c73e 100644 --- a/frontend/src/app/docs/api-docs/api-docs-data.ts +++ b/frontend/src/app/docs/api-docs/api-docs-data.ts @@ -12136,13 +12136,13 @@ export const restApiDocsData = [ Filters can be applied:
  • status: all, requested, accelerating, mined, completed, failed
  • timeframe: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y, 4y, all
  • -
  • minedByPoolUniqueId: any id from pools-v2.json -
  • blockHash: a block hash -
  • blockHeight: a block height -
  • page: the requested page number if using pagination (min: 1) -
  • pageLength: the page lenght if using pagination (min: 1, max: 50) -
  • from: unix timestamp (overrides timeframe) -
  • to: unix timestamp (overrides timeframe) +
  • minedByPoolUniqueId: any id from pools-v2.json
  • +
  • blockHash: a block hash
  • +
  • blockHeight: a block height
  • +
  • page: the requested page number if using pagination (min: 1)
  • +
  • pageLength: the page length if using pagination (min: 1, max: 50)
  • +
  • from: unix timestamp (overrides timeframe)
  • +
  • to: unix timestamp (overrides timeframe)

` }, urlString: '/v1/services/accelerator/accelerations/history', @@ -12184,6 +12184,65 @@ export const restApiDocsData = [ } } }, + { + options: { officialOnly: true }, + type: 'endpoint', + category: 'accelerator-public', + httpRequestMethod: 'GET', + fragment: 'accelerator-public-stats', + title: 'GET Acceleration Stats', + description: { + default: `

Aggregated statistics for transaction accelerations, with optional filtering by pool, block, or time range. + Filters can be applied:

    +
  • timeframe: 24h, 3d, 1w, 1m, 3m, 6m, 1y, 2y, 3y, 4y, all
  • +
  • poolUniqueId: any id from pools-v2.json
  • +
  • blockHash: a block hash
  • +
  • blockHeight: a block height
  • +
  • from: unix timestamp (overrides timeframe)
  • +
  • to: unix timestamp (overrides timeframe)
  • +

+

+ Response fields: +

    +
  • totalRequested: number of acceleration requests.
  • +
  • totalAccepted: accelerations accepted into a block template. +
    - Per-pool: count this pool put in its template. +
    - Global: count accepted by any pool. Per-pool values do not sum to the global value.
  • +
  • totalCompleted: accelerations mined into a confirmed block. Per-pool values sum to roughly the global value.
  • +
  • totalBidBoost: total acceleration fees in sats.
  • +
  • totalVsize: Total virtual size of accelerated transactions, in vbytes.
  • +
+

+ ` + }, + urlString: '/v1/services/accelerator/accelerations/stats', + showConditions: [''], + showJsExamples: showJsExamplesDefaultFalse, + codeExample: { + default: { + codeTemplate: { + curl: `/api/v1/services/accelerator/accelerations/stats?blockHash=000000000000000000002c55e353486c1013ce8bd6d637fd5be7798f44b731dc`, + commonJS: ``, + esModule: `` + }, + codeSampleMainnet: { + esModule: [], + commonJS: [], + curl: [], + headers: '', + response: ` + { + "totalRequested": 3, + "totalAccepted": 3, + "totalCompleted": 3, + "totalBidBoost": 1552, + "totalVsize": 1846 + } +`, + }, + }, + } + }, // ACCELERATOR AUTHENTICATED { diff --git a/frontend/src/app/interfaces/node-api.interface.ts b/frontend/src/app/interfaces/node-api.interface.ts index a48ff3f05..a76a2d2be 100644 --- a/frontend/src/app/interfaces/node-api.interface.ts +++ b/frontend/src/app/interfaces/node-api.interface.ts @@ -447,11 +447,13 @@ export interface Acceleration { export interface AccelerationHistoryParams { status?: string; // Single status or comma separated list of status timeframe?: string; - poolUniqueId?: number; + minedByPoolUniqueId?: number; blockHash?: string; blockHeight?: number; page?: number; pageLength?: number; + from?: number; + to?: number; } export interface AccelerationInfo { From 2fe8a4ce18e06b96541246cff256b393097bcc54 Mon Sep 17 00:00:00 2001 From: Felipe Knorr Kuhn Date: Sat, 9 May 2026 01:46:05 +0900 Subject: [PATCH 10/17] Update provenance check json keys --- .github/workflows/dependabot-provenance-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-provenance-check.yml b/.github/workflows/dependabot-provenance-check.yml index 108b1c00f..41fb2abd9 100644 --- a/.github/workflows/dependabot-provenance-check.yml +++ b/.github/workflows/dependabot-provenance-check.yml @@ -44,7 +44,7 @@ jobs: DEP=$(echo "$DEP" | xargs) NEW_VERSION=$(echo "$UPDATED_DEPS_JSON" | jq -r --arg name "$DEP" ' - .[] | select(.["dependency-name"] == $name) | .["new-version"] + .[] | select(.dependencyName == $name) | .newVersion ' | head -n 1) if [ -z "$NEW_VERSION" ] || [ "$NEW_VERSION" = "null" ]; then From 22ed2e646881fbc5e8218d7291a6320bb7a5c6a1 Mon Sep 17 00:00:00 2001 From: wiz Date: Sat, 9 May 2026 10:49:55 -0600 Subject: [PATCH 11/17] Remove "click for more details" from cluster preview tooltip --- .../transaction-details/transaction-details.component.html | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html index cf60994f8..f6decfacf 100644 --- a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html +++ b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html @@ -268,7 +268,6 @@ } @else if (clusterPreviewStats.otherChunks > 1) {

In a mempool cluster containing {{ clusterPreviewStats.otherChunks }} other chunks.

} -

Click for more details.

From 3b8a1b106338295f002c398d28fe99a8b7a81d81 Mon Sep 17 00:00:00 2001 From: nymkappa Date: Sat, 9 May 2026 21:12:51 +0200 Subject: [PATCH 12/17] [about] rewrite alliances html/css and add BDK logo --- .../app/components/about/about.component.html | 42 ++++++++++------ .../app/components/about/about.component.scss | 49 ++++++------------- .../src/resources/profile/bdk-simple-logo.svg | 31 ++++++++++++ 3 files changed, 73 insertions(+), 49 deletions(-) create mode 100644 frontend/src/resources/profile/bdk-simple-logo.svg diff --git a/frontend/src/app/components/about/about.component.html b/frontend/src/app/components/about/about.component.html index 60a71fa77..5fbcc69cc 100644 --- a/frontend/src/app/components/about/about.component.html +++ b/frontend/src/app/components/about/about.component.html @@ -408,25 +408,37 @@

Community Alliances

- diff --git a/frontend/src/app/components/about/about.component.scss b/frontend/src/app/components/about/about.component.scss index 8eea36137..28aeda160 100644 --- a/frontend/src/app/components/about/about.component.scss +++ b/frontend/src/app/components/about/about.component.scss @@ -101,42 +101,23 @@ } } - .alliances { - margin-bottom: 100px; - a { - &:nth-child(3) { - position: relative; - top: 10px; - } + .alliances-logos { + align-items: center; + margin-bottom: 80px; + } + .alliance-logo { + height: 80px; + display: flex; + justify-content: center; + margin-top: 25px; + @media (min-width: 768px) { + margin-top: 45px; } - img { - display: inline-block; - margin: 15px auto; - height: 62px; - @media (min-width: 425px) { - margin: 15px 60px; - } - @media (min-width: 576px) { - margin: 15px 120px; - } - @media (min-width: 850px) { - margin: 50px 30px 0px; - } - } - .liquid { - top: 7px; - position: relative; - } - .copa { - height: auto; - top: 23px; - position: relative; - width: 300px; - } - .sv { - height: 85px; - width: auto; + } + .copa { + @media (min-width: 992px) { position: relative; + top: 15px; } } diff --git a/frontend/src/resources/profile/bdk-simple-logo.svg b/frontend/src/resources/profile/bdk-simple-logo.svg new file mode 100644 index 000000000..57c164326 --- /dev/null +++ b/frontend/src/resources/profile/bdk-simple-logo.svg @@ -0,0 +1,31 @@ + + + BDK Simple Logo + Foundation + + + + + + + + + + + + + + + + BDK + Foundation + + From 325423e3da9237cdf62526dc3f9ec926247159a4 Mon Sep 17 00:00:00 2001 From: mononaut Date: Mon, 11 May 2026 06:27:02 +0000 Subject: [PATCH 13/17] bump angular dependencies --- frontend/package-lock.json | 2598 +++++++++++++++++++++++++----------- frontend/package.json | 30 +- 2 files changed, 1857 insertions(+), 771 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 1040890f5..06ebe6778 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,19 +9,19 @@ "version": "3.4-dev", "license": "GNU Affero General Public License v3.0", "dependencies": { - "@angular-devkit/build-angular": "^20.3.20", - "@angular/animations": "^20.3.18", - "@angular/cli": "^20.3.20", - "@angular/common": "^20.3.18", - "@angular/compiler": "^20.3.18", - "@angular/core": "^20.3.18", - "@angular/forms": "^20.3.18", - "@angular/localize": "^20.3.18", - "@angular/platform-browser": "^20.3.18", - "@angular/platform-browser-dynamic": "^20.3.18", - "@angular/platform-server": "^20.3.18", - "@angular/router": "^20.3.18", - "@angular/ssr": "^20.3.18", + "@angular-devkit/build-angular": "^20.3.25", + "@angular/animations": "^20.3.19", + "@angular/cli": "^20.3.25", + "@angular/common": "^20.3.19", + "@angular/compiler": "^20.3.19", + "@angular/core": "^20.3.19", + "@angular/forms": "^20.3.19", + "@angular/localize": "^20.3.19", + "@angular/platform-browser": "^20.3.19", + "@angular/platform-browser-dynamic": "^20.3.19", + "@angular/platform-server": "^20.3.19", + "@angular/router": "^20.3.19", + "@angular/ssr": "^20.3.25", "@fortawesome/angular-fontawesome": "^3.0.0", "@fortawesome/fontawesome-common-types": "~6.7.2", "@fortawesome/fontawesome-svg-core": "~6.7.2", @@ -31,7 +31,6 @@ "@types/qrcode": "~1.5.0", "bootstrap": "~5.3.8", "clipboard": "^2.0.11", - "cypress": "15.13.0", "domino": "^2.1.6", "echarts": "~5.4.0", "ngx-echarts": "~20.0.2", @@ -42,8 +41,8 @@ "zone.js": "~0.15.1" }, "devDependencies": { - "@angular/compiler-cli": "^20.3.18", - "@angular/language-service": "^20.3.18", + "@angular/compiler-cli": "^20.3.19", + "@angular/language-service": "^20.3.19", "@types/node": "^24.9.2", "@typescript-eslint/eslint-plugin": "^8.46.2", "@typescript-eslint/parser": "^8.46.2", @@ -281,12 +280,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.2003.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2003.20.tgz", - "integrity": "sha512-1g7q37Aq4dvDdQDW0PtWXfiX5hBV78K74QUtFkAXGIXU3DkguwOQaqHILCnIRAVr0wFlWDckWVuO5OT6Cl9HeQ==", + "version": "0.2003.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2003.25.tgz", + "integrity": "sha512-39pTqt4wSmpD1WeCee46oSGXRh6TR1PFd9GZEwyZoMvBTMs8mE2sXGxUgd4Qyi5CkQ1XnCM5XfgJcjUWUQRoGg==", "license": "MIT", "dependencies": { - "@angular-devkit/core": "20.3.20", + "@angular-devkit/core": "20.3.25", "rxjs": "7.8.2" }, "engines": { @@ -296,15 +295,15 @@ } }, "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.20.tgz", - "integrity": "sha512-Iobw7He3yJVR2aQ6JN9Kq/2ldD8+uHzJZwd41SQ91A+TzPrBRSV0t80WHHrANZ7xnAjtHDc7zSSGp/i7DzUc9g==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.25.tgz", + "integrity": "sha512-pSfeWEoS1y9zxqTOw0Etj2NXkRmp/aU52wdnyq3KqVA9cJtgxtlOHlBBNswTil4dReojEy+0K1xJm+mLuWuLxA==", "license": "MIT", "dependencies": { "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "rxjs": "7.8.2", "source-map": "0.7.6" }, @@ -355,22 +354,6 @@ } } }, - "node_modules/@angular-devkit/architect/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/architect/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -378,9 +361,9 @@ "license": "MIT" }, "node_modules/@angular-devkit/architect/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==", "license": "MIT", "engines": { "node": ">=12" @@ -389,20 +372,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@angular-devkit/architect/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/architect/node_modules/source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", @@ -413,16 +382,16 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.3.20.tgz", - "integrity": "sha512-ihBD8zsRoMsuwS3KkwqwwlJGw5jcLerG8zy1kdSEsdJwIYjITgMdV+iK02uSWptLTDd3ILOdgcoZzipcEwJX4w==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.3.25.tgz", + "integrity": "sha512-jp2sbJhbVRT65RbGENY/lz3Z0W0D50Af3xzENmLDLBVp9uhlpIPSTC9LG4CEPV7T6H5Oq6ymHKM+OO5WwTlHHA==", "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2003.20", - "@angular-devkit/build-webpack": "0.2003.20", - "@angular-devkit/core": "20.3.20", - "@angular/build": "20.3.20", + "@angular-devkit/architect": "0.2003.25", + "@angular-devkit/build-webpack": "0.2003.25", + "@angular-devkit/core": "20.3.25", + "@angular/build": "20.3.25", "@babel/core": "7.28.3", "@babel/generator": "7.28.3", "@babel/helper-annotate-as-pure": "7.27.3", @@ -433,14 +402,14 @@ "@babel/preset-env": "7.28.3", "@babel/runtime": "7.28.3", "@discoveryjs/json-ext": "0.6.3", - "@ngtools/webpack": "20.3.20", + "@ngtools/webpack": "20.3.25", "ansi-colors": "4.1.3", "autoprefixer": "10.4.21", "babel-loader": "10.0.0", "browserslist": "^4.21.5", "copy-webpack-plugin": "14.0.0", "css-loader": "7.1.2", - "esbuild-wasm": "0.25.9", + "esbuild-wasm": "0.28.0", "fast-glob": "3.3.3", "http-proxy-middleware": "3.0.5", "istanbul-lib-instrument": "6.0.3", @@ -453,9 +422,9 @@ "mini-css-extract-plugin": "2.9.4", "open": "10.2.0", "ora": "8.2.0", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "piscina": "5.1.3", - "postcss": "8.5.6", + "postcss": "8.5.12", "postcss-loader": "8.1.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.2", @@ -479,7 +448,7 @@ "yarn": ">= 1.13.0" }, "optionalDependencies": { - "esbuild": "0.25.9" + "esbuild": "0.28.0" }, "peerDependencies": { "@angular/compiler-cli": "^20.0.0", @@ -488,7 +457,7 @@ "@angular/platform-browser": "^20.0.0", "@angular/platform-server": "^20.0.0", "@angular/service-worker": "^20.0.0", - "@angular/ssr": "^20.3.20", + "@angular/ssr": "^20.3.25", "@web/test-runner": "^0.20.0", "browser-sync": "^3.0.2", "jest": "^29.5.0 || ^30.2.0", @@ -545,15 +514,15 @@ } }, "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.20.tgz", - "integrity": "sha512-Iobw7He3yJVR2aQ6JN9Kq/2ldD8+uHzJZwd41SQ91A+TzPrBRSV0t80WHHrANZ7xnAjtHDc7zSSGp/i7DzUc9g==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.25.tgz", + "integrity": "sha512-pSfeWEoS1y9zxqTOw0Etj2NXkRmp/aU52wdnyq3KqVA9cJtgxtlOHlBBNswTil4dReojEy+0K1xJm+mLuWuLxA==", "license": "MIT", "dependencies": { "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "rxjs": "7.8.2", "source-map": "0.7.6" }, @@ -571,6 +540,422 @@ } } }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/aix-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/android-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/android-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/android-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/darwin-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/darwin-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/freebsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-loong64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-mips64el": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-riscv64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-s390x": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/netbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/openbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/sunos-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/win32-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/win32-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/win32-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@angular-devkit/build-angular/node_modules/ajv": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", @@ -604,22 +989,6 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/build-angular/node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -637,6 +1006,48 @@ } } }, + "node_modules/@angular-devkit/build-angular/node_modules/esbuild": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" + } + }, "node_modules/@angular-devkit/build-angular/node_modules/http-proxy-middleware": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", @@ -685,9 +1096,9 @@ "license": "MIT" }, "node_modules/@angular-devkit/build-angular/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==", "license": "MIT", "engines": { "node": ">=12" @@ -696,20 +1107,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@angular-devkit/build-angular/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/build-angular/node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -750,12 +1147,12 @@ } }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.2003.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2003.20.tgz", - "integrity": "sha512-WLeYLFxRnEYwCrPUx8qciWs+PrJKDp71ZsIRqeFCcpB8qFQOgR/CjPZYxZFqAnuTJtM4MqCtczvmn57ulKTPcA==", + "version": "0.2003.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2003.25.tgz", + "integrity": "sha512-jJMpYBdWeRfvrCna7JWsyMBbvjMcPblyzh4/pSfWw5znla3hJGzDtmb84qKZ+IB8eZNEcky4iGR5LK2jdGFLAg==", "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.2003.20", + "@angular-devkit/architect": "0.2003.25", "rxjs": "7.8.2" }, "engines": { @@ -769,12 +1166,12 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.20.tgz", - "integrity": "sha512-+NNHQhQHcgQWZopStZ6os30YuP99lRzNS4wOnkJmoROy40SZct8lPnl2QW50a9Vc0AtaHx1a1NUZ+ohbf6fXqw==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.25.tgz", + "integrity": "sha512-IB0IHf8ZRqr69hT/XIfHkYLPAYHWQ/WUc6+fKHBwq58jJlm/y5QUeTEuXvJ18IX/+hUIqw+E2Q3T0N9rLDLzXg==", "license": "MIT", "dependencies": { - "@angular-devkit/core": "20.3.20", + "@angular-devkit/core": "20.3.25", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "8.2.0", @@ -787,15 +1184,15 @@ } }, "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.20.tgz", - "integrity": "sha512-Iobw7He3yJVR2aQ6JN9Kq/2ldD8+uHzJZwd41SQ91A+TzPrBRSV0t80WHHrANZ7xnAjtHDc7zSSGp/i7DzUc9g==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.25.tgz", + "integrity": "sha512-pSfeWEoS1y9zxqTOw0Etj2NXkRmp/aU52wdnyq3KqVA9cJtgxtlOHlBBNswTil4dReojEy+0K1xJm+mLuWuLxA==", "license": "MIT", "dependencies": { "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "rxjs": "7.8.2", "source-map": "0.7.6" }, @@ -846,22 +1243,6 @@ } } }, - "node_modules/@angular-devkit/schematics/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/schematics/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -869,9 +1250,9 @@ "license": "MIT" }, "node_modules/@angular-devkit/schematics/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==", "license": "MIT", "engines": { "node": ">=12" @@ -880,20 +1261,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@angular-devkit/schematics/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/schematics/node_modules/source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", @@ -904,9 +1271,9 @@ } }, "node_modules/@angular/animations": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.18.tgz", - "integrity": "sha512-XFxgSyjfs0SRD2vQVFJljmM4z9nTvUoI8TRqSre/+l8D2FgzD5pG67Aj2BgDgpSFAUkIcI37G48ijK7a3ZZ3WA==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.19.tgz", + "integrity": "sha512-/FjU9i7J58/yBURhgVSIiLDcuyOfJxAa0b7ZrOsx6P+FES+M2T2BKZl5V2NuiP2fDFtjsV7U+M/Z9UNUmeHCEw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -915,17 +1282,17 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/core": "20.3.18" + "@angular/core": "20.3.19" } }, "node_modules/@angular/build": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.3.20.tgz", - "integrity": "sha512-+uWqGU+Qyso2uJKL1xNjAm+E3m3ncv5InMUG5BC/UhFnXTsL1o7oySGc6hHa+8rQunuifUhdy20HxZjU6QlqTw==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.3.25.tgz", + "integrity": "sha512-ddWmPzYuzDWz9ql0262u9w3OJHXpSjHVNIDFIYOG2XYyMj/Xve0RkJ8/xvV+Hv7T3iqyyGKtsO+n/d0GCJQCtQ==", "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2003.20", + "@angular-devkit/architect": "0.2003.25", "@babel/core": "7.28.3", "@babel/helper-annotate-as-pure": "7.27.3", "@babel/helper-split-export-declaration": "7.24.7", @@ -933,7 +1300,7 @@ "@vitejs/plugin-basic-ssl": "2.1.0", "beasties": "0.3.5", "browserslist": "^4.23.0", - "esbuild": "0.25.9", + "esbuild": "0.28.0", "https-proxy-agent": "7.0.6", "istanbul-lib-instrument": "6.0.3", "jsonc-parser": "3.3.1", @@ -941,14 +1308,14 @@ "magic-string": "0.30.17", "mrmime": "2.0.1", "parse5-html-rewriting-stream": "8.0.0", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "piscina": "5.1.3", "rollup": "4.59.0", "sass": "1.90.0", "semver": "7.7.2", "source-map-support": "0.5.21", "tinyglobby": "0.2.14", - "vite": "7.1.11", + "vite": "7.3.2", "watchpack": "2.4.4" }, "engines": { @@ -967,7 +1334,7 @@ "@angular/platform-browser": "^20.0.0", "@angular/platform-server": "^20.0.0", "@angular/service-worker": "^20.0.0", - "@angular/ssr": "^20.3.20", + "@angular/ssr": "^20.3.25", "karma": "^6.4.0", "less": "^4.2.0", "ng-packagr": "^20.0.0", @@ -1016,6 +1383,422 @@ } } }, + "node_modules/@angular/build/node_modules/@esbuild/aix-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/android-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/android-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/android-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/darwin-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/darwin-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/freebsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/linux-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/linux-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/linux-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/linux-loong64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/linux-mips64el": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/linux-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/linux-riscv64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/linux-s390x": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/linux-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/netbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/openbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/sunos-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/win32-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/win32-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/@esbuild/win32-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@angular/build/node_modules/ansi-escapes": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", @@ -1092,6 +1875,47 @@ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "license": "MIT" }, + "node_modules/@angular/build/node_modules/esbuild": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" + } + }, "node_modules/@angular/build/node_modules/eventemitter3": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", @@ -1193,9 +2017,9 @@ } }, "node_modules/@angular/build/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==", "license": "MIT", "engines": { "node": ">=12" @@ -1310,18 +2134,18 @@ } }, "node_modules/@angular/cli": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.3.20.tgz", - "integrity": "sha512-wHMo0BWhoBMXcsZ1U+yJ0eOH2B5NgCWW7PTrJ1P/QbocbCSh7eqw8wKnEthIKyhrEWtAo67Jw7i8CgbeIZgmMw==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.3.25.tgz", + "integrity": "sha512-QOSxza45CZY11kqPVpqsU+WGYF99rR/r9A9GykZQWuAHb5SEAxlXHyaaGMu/BMtBHy5HNIlJH25UlzelrbaNyQ==", "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.2003.20", - "@angular-devkit/core": "20.3.20", - "@angular-devkit/schematics": "20.3.20", + "@angular-devkit/architect": "0.2003.25", + "@angular-devkit/core": "20.3.25", + "@angular-devkit/schematics": "20.3.25", "@inquirer/prompts": "7.8.2", "@listr2/prompt-adapter-inquirer": "3.0.1", "@modelcontextprotocol/sdk": "1.26.0", - "@schematics/angular": "20.3.20", + "@schematics/angular": "20.3.25", "@yarnpkg/lockfile": "1.1.0", "algoliasearch": "5.35.0", "ini": "5.0.0", @@ -1344,15 +2168,15 @@ } }, "node_modules/@angular/cli/node_modules/@angular-devkit/core": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.20.tgz", - "integrity": "sha512-Iobw7He3yJVR2aQ6JN9Kq/2ldD8+uHzJZwd41SQ91A+TzPrBRSV0t80WHHrANZ7xnAjtHDc7zSSGp/i7DzUc9g==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.25.tgz", + "integrity": "sha512-pSfeWEoS1y9zxqTOw0Etj2NXkRmp/aU52wdnyq3KqVA9cJtgxtlOHlBBNswTil4dReojEy+0K1xJm+mLuWuLxA==", "license": "MIT", "dependencies": { "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "rxjs": "7.8.2", "source-map": "0.7.6" }, @@ -1458,22 +2282,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@angular/cli/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular/cli/node_modules/cli-cursor": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", @@ -1618,9 +2426,9 @@ } }, "node_modules/@angular/cli/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==", "license": "MIT", "engines": { "node": ">=12" @@ -1629,20 +2437,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@angular/cli/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular/cli/node_modules/restore-cursor": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", @@ -1758,9 +2552,9 @@ } }, "node_modules/@angular/common": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.18.tgz", - "integrity": "sha512-M62oQbSTRmnGavIVCwimoadg/PDWadgNhactMm9fgH0eM9rx+iWBAYJk4VufO0bwOhysFpRZpJgXlFjOifz/Jw==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.19.tgz", + "integrity": "sha512-hcB1eUEN8LGcKGc4DlRJ+abS6AYfbEHDZKg8LnXNugkbwI6Ebyh2AUYTDhzZL2S4aH+C8biHKgSYHFCqieCRhA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1769,14 +2563,14 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/core": "20.3.18", + "@angular/core": "20.3.19", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.18.tgz", - "integrity": "sha512-AaP/LCiDNcYmF135EEozjyR04NRBT38ZfBHQwjhgwiBBTejmvcpHwJaHSkraLpZqZzE4BQqqmgiQ1EJqxEwLVA==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.19.tgz", + "integrity": "sha512-ETkgDKm0l2PuaBubgPJe0ccy8kE75DFu6/zKcz7TUuk3KrKF2OZAopbbjftsUSZGeCNvCdqHzjmcL6hQ6oAOwA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1786,9 +2580,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.18.tgz", - "integrity": "sha512-zsoEgLgnblmRbi47YwMghKirJ8IBKJ3+I8TxLBRIBrhx+KHFp+6oeDeLyu9H+djdyk88zexVd09wzR/YK73F0g==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.19.tgz", + "integrity": "sha512-ET/JjO8s62kAHfgIsGXlvW5VUwLqHm03q1y/2yD7aQW/WdDvssMsvZv7Knl440989vdOFemIGTMwVPakmWqRmA==", "license": "MIT", "dependencies": { "@babel/core": "7.28.3", @@ -1808,7 +2602,7 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "20.3.18", + "@angular/compiler": "20.3.19", "typescript": ">=5.8 <6.0" }, "peerDependenciesMeta": { @@ -1846,9 +2640,9 @@ } }, "node_modules/@angular/core": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.18.tgz", - "integrity": "sha512-B+NQQngd/aDbcfW0zGLis3wTLDeHTeTYMl/mGKQH+HwdPaRCKI1wEtaXaOYVJXkP2FeThocPevB8gLwNlPQUUw==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.19.tgz", + "integrity": "sha512-SYnwW+q51bQoPtGFoGovm1P5GK9fMEXsG0lGaEAUapjskblAYyX7hLlM/jgueSojv2SjhqNF8aXR+gjHLhZVNA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1857,7 +2651,7 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "20.3.18", + "@angular/compiler": "20.3.19", "rxjs": "^6.5.3 || ^7.4.0", "zone.js": "~0.15.0" }, @@ -1871,9 +2665,9 @@ } }, "node_modules/@angular/forms": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.18.tgz", - "integrity": "sha512-x6/99LfxolyZIFUL3Wr0OrtuXHEDwEz/rwx+WzE7NL+n35yO40t3kp0Sn5uMFwI94i91QZJmXHltMpZhrVLuYg==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.19.tgz", + "integrity": "sha512-WJotd+Lhl4FG2b0K+aQNyQDHhR515zKCuphjiUqEW7sifWrOQxANLKzPBngGrH75ayANFgPaDf7U3ZRIoblcQA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1882,16 +2676,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.3.18", - "@angular/core": "20.3.18", - "@angular/platform-browser": "20.3.18", + "@angular/common": "20.3.19", + "@angular/core": "20.3.19", + "@angular/platform-browser": "20.3.19", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/language-service": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-20.3.18.tgz", - "integrity": "sha512-V1ZBqeTtZYH9H8/G1qCw6gafsJmhMIMFjLX0Hv2KpTpmfK9nxIHPEVnshr3xT+qKYJIrMV/cU5YOzInEapLpuQ==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-20.3.19.tgz", + "integrity": "sha512-9J0XrAKXInz11KKyNMrMZmn2NSjVbxzt/DsAumbrzzixeZwiY7vDy2Kqw/LLFLi7IlfMQ/gznz/mCVVgUWI5Gg==", "dev": true, "license": "MIT", "engines": { @@ -1899,9 +2693,9 @@ } }, "node_modules/@angular/localize": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-20.3.18.tgz", - "integrity": "sha512-Zx7LiyMjTvooPhy/r6RoyWzGECfWiA8jH4zwsa/xPF6RX8MD/hOi8vcS4UxTdLSWB4lM5ZtSifAnOfwcm/0CyQ==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-20.3.19.tgz", + "integrity": "sha512-bXOwxzJUvHzmADI6czdjYnuBMil/UK3CW1dfbrC1MrlLtD0R7g4YZs08J7aWXd+/A4LmTPfkpZhI5ApxGAL0Tg==", "license": "MIT", "dependencies": { "@babel/core": "7.28.3", @@ -1918,14 +2712,14 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "20.3.18", - "@angular/compiler-cli": "20.3.18" + "@angular/compiler": "20.3.19", + "@angular/compiler-cli": "20.3.19" } }, "node_modules/@angular/platform-browser": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.18.tgz", - "integrity": "sha512-q6s5rEN1yYazpHYp+k4pboXRzMsRB9auzTRBEhyXSGYxqzrnn3qHN0DqgsLC9WAdyhCgnIEMFA8kRT+W277DqQ==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.19.tgz", + "integrity": "sha512-TRZfatH1B/kreDwFRwtpLEurJQ6044qh6DWpvxzTbugaG5otLQJKTk+1z81/KsJwQqc1+24v+yuywc1LM7aq7w==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1934,9 +2728,9 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/animations": "20.3.18", - "@angular/common": "20.3.18", - "@angular/core": "20.3.18" + "@angular/animations": "20.3.19", + "@angular/common": "20.3.19", + "@angular/core": "20.3.19" }, "peerDependenciesMeta": { "@angular/animations": { @@ -1945,9 +2739,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.18.tgz", - "integrity": "sha512-NyTobOGYVzGmPmtI+3lxMzxi0TbLq4SRNQ2ENEJAt6k2JnMmHBm483ppLRAM47nGlDdiraW0IX93EtYYNkiK3g==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.19.tgz", + "integrity": "sha512-OgErw7wjcC+8yKF5h99hJq8x+tvc091wThfmdL5YC+U3HgRmUaNZFgB/jR7cb/NeeeC42QW5Vc0qoUTC9rMnLQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1956,16 +2750,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.3.18", - "@angular/compiler": "20.3.18", - "@angular/core": "20.3.18", - "@angular/platform-browser": "20.3.18" + "@angular/common": "20.3.19", + "@angular/compiler": "20.3.19", + "@angular/core": "20.3.19", + "@angular/platform-browser": "20.3.19" } }, "node_modules/@angular/platform-server": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-20.3.18.tgz", - "integrity": "sha512-iw4QSmEWEKbyMT5u8QdhalNiPqRc7cRuo6lulU75pjXqVLwLb3Gq8it+Vo+LSKY6qI/bMO7olS7iyw09wXJ0OQ==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-20.3.19.tgz", + "integrity": "sha512-9STNB8Z5uYpaIgzfiJOH81c4CY2lM3oq/650+pdnjJsedxyEi+NAbnn5tF857Cd/N+43lR+OMolKgm0MJziHqw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0", @@ -1975,17 +2769,17 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.3.18", - "@angular/compiler": "20.3.18", - "@angular/core": "20.3.18", - "@angular/platform-browser": "20.3.18", + "@angular/common": "20.3.19", + "@angular/compiler": "20.3.19", + "@angular/core": "20.3.19", + "@angular/platform-browser": "20.3.19", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/router": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.18.tgz", - "integrity": "sha512-3CWejsEYr+ze+ktvWN/qHdyq5WLrj96QZpGYJyxh1pchIcpMPE9MmLpdjf0CUrWYB7g/85u0Geq/xsz72JrGng==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.19.tgz", + "integrity": "sha512-qHrMniHOsCJ4neZmcQVodjutJilyXAXk7EhLa931QyL0qyVKVomv6E0I3UFzRaC3ZeHc+hzBdU6C6bvMFKTl1g==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1994,16 +2788,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.3.18", - "@angular/core": "20.3.18", - "@angular/platform-browser": "20.3.18", + "@angular/common": "20.3.19", + "@angular/core": "20.3.19", + "@angular/platform-browser": "20.3.19", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/ssr": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-20.3.20.tgz", - "integrity": "sha512-DA/rp8BoaBAOQmRVd2+zgvJilrwmv60CVidC8bf9aF0oURQyD/LpcTAaGKrGf4DEoulsXdDvKEI+WN7oUJs56A==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-20.3.25.tgz", + "integrity": "sha512-A/lbXQ+GucLAQfCJ5img7/xuqlftWjJU+iJABq/ARDkOOE/rNHrxFkXjJBntj97+oXjr7HBYI2sxYRZCCEiEag==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -3720,12 +4514,13 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", - "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", "cpu": [ "ppc64" ], + "license": "MIT", "optional": true, "os": [ "aix" @@ -3735,12 +4530,13 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", - "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -3750,12 +4546,13 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", - "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -3765,12 +4562,13 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", - "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -3780,12 +4578,13 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", - "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3795,12 +4594,13 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", - "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3810,12 +4610,13 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", - "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -3825,12 +4626,13 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", - "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -3840,12 +4642,13 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", - "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -3855,12 +4658,13 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", - "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -3870,12 +4674,13 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", - "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -3885,12 +4690,13 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", - "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", "cpu": [ "loong64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -3900,12 +4706,13 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", - "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", "cpu": [ "mips64el" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -3915,12 +4722,13 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", - "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", "cpu": [ "ppc64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -3930,12 +4738,13 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", - "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", "cpu": [ "riscv64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -3945,12 +4754,13 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", - "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", "cpu": [ "s390x" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -3960,12 +4770,13 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", - "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -3975,12 +4786,13 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", - "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -3990,12 +4802,13 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", - "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -4005,12 +4818,13 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", - "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -4020,12 +4834,13 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", - "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -4035,12 +4850,13 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", - "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "openharmony" @@ -4050,12 +4866,13 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", - "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "sunos" @@ -4065,12 +4882,13 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", - "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -4080,12 +4898,13 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", - "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -4095,12 +4914,13 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", - "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -5859,9 +6679,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.3.20.tgz", - "integrity": "sha512-5azJ9+W/aMFR4C38ShoWib6xW5ou5Q5yeup+6skpvrud5mAAj3e36S5diYYXqbzVfo3DM+sWueDRNP3DV7IHhg==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.3.25.tgz", + "integrity": "sha512-p/YopAgukaIvezv3hsJzJevnNUBNTM8UQIkyDHPY5/aANdKraUTKDQUwlVxRiyD8U+PTSeD/BI56oOnuKrdFZQ==", "license": "MIT", "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", @@ -6792,13 +7612,13 @@ ] }, "node_modules/@schematics/angular": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.3.20.tgz", - "integrity": "sha512-LyoHwenNi8lZZO5zafAjcN8DcaOdjFrkbZdrCkvdpmOFz5wy8ZGchY6XSZEDD6kdHvR8oU7WWnGTMgCfExBKCg==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.3.25.tgz", + "integrity": "sha512-ezoJpPKhhjXgE3LxuNcJO/ghSXs8f73xrqGvqouag7IbuliJYbHrt22WH3X75XSbD0+iOdiqA2bARvAO/ezyxQ==", "license": "MIT", "dependencies": { - "@angular-devkit/core": "20.3.20", - "@angular-devkit/schematics": "20.3.20", + "@angular-devkit/core": "20.3.25", + "@angular-devkit/schematics": "20.3.25", "jsonc-parser": "3.3.1" }, "engines": { @@ -6808,15 +7628,15 @@ } }, "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.20.tgz", - "integrity": "sha512-Iobw7He3yJVR2aQ6JN9Kq/2ldD8+uHzJZwd41SQ91A+TzPrBRSV0t80WHHrANZ7xnAjtHDc7zSSGp/i7DzUc9g==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.25.tgz", + "integrity": "sha512-pSfeWEoS1y9zxqTOw0Etj2NXkRmp/aU52wdnyq3KqVA9cJtgxtlOHlBBNswTil4dReojEy+0K1xJm+mLuWuLxA==", "license": "MIT", "dependencies": { "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "rxjs": "7.8.2", "source-map": "0.7.6" }, @@ -6867,22 +7687,6 @@ } } }, - "node_modules/@schematics/angular/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@schematics/angular/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -6890,9 +7694,9 @@ "license": "MIT" }, "node_modules/@schematics/angular/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==", "license": "MIT", "engines": { "node": ">=12" @@ -6901,20 +7705,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@schematics/angular/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@schematics/angular/node_modules/source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", @@ -10388,10 +11178,11 @@ } }, "node_modules/esbuild": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", - "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -10399,38 +11190,38 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.9", - "@esbuild/android-arm": "0.25.9", - "@esbuild/android-arm64": "0.25.9", - "@esbuild/android-x64": "0.25.9", - "@esbuild/darwin-arm64": "0.25.9", - "@esbuild/darwin-x64": "0.25.9", - "@esbuild/freebsd-arm64": "0.25.9", - "@esbuild/freebsd-x64": "0.25.9", - "@esbuild/linux-arm": "0.25.9", - "@esbuild/linux-arm64": "0.25.9", - "@esbuild/linux-ia32": "0.25.9", - "@esbuild/linux-loong64": "0.25.9", - "@esbuild/linux-mips64el": "0.25.9", - "@esbuild/linux-ppc64": "0.25.9", - "@esbuild/linux-riscv64": "0.25.9", - "@esbuild/linux-s390x": "0.25.9", - "@esbuild/linux-x64": "0.25.9", - "@esbuild/netbsd-arm64": "0.25.9", - "@esbuild/netbsd-x64": "0.25.9", - "@esbuild/openbsd-arm64": "0.25.9", - "@esbuild/openbsd-x64": "0.25.9", - "@esbuild/openharmony-arm64": "0.25.9", - "@esbuild/sunos-x64": "0.25.9", - "@esbuild/win32-arm64": "0.25.9", - "@esbuild/win32-ia32": "0.25.9", - "@esbuild/win32-x64": "0.25.9" + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" } }, "node_modules/esbuild-wasm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.9.tgz", - "integrity": "sha512-Jpv5tCSwQg18aCqCRD3oHIX/prBhXMDapIoG//A+6+dV0e7KQMGFg85ihJ5T1EeMjbZjON3TqFy0VrGAnIHLDA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.28.0.tgz", + "integrity": "sha512-5TRVKExcEmeMkccIZMzUq+Az6X2RoMAJyfl6SMMO1dMVhmvt0I2mx7gAb6zYi42n4d1ETcatFXazGKzA+aW7fg==", "license": "MIT", "bin": { "esbuild": "bin/esbuild" @@ -14738,9 +15529,9 @@ } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.12.tgz", + "integrity": "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==", "funding": [ { "type": "opencollective", @@ -17150,11 +17941,12 @@ } }, "node_modules/vite": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.11.tgz", - "integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", + "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", + "license": "MIT", "dependencies": { - "esbuild": "^0.25.0", + "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", @@ -18210,23 +19002,23 @@ } }, "@angular-devkit/architect": { - "version": "0.2003.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2003.20.tgz", - "integrity": "sha512-1g7q37Aq4dvDdQDW0PtWXfiX5hBV78K74QUtFkAXGIXU3DkguwOQaqHILCnIRAVr0wFlWDckWVuO5OT6Cl9HeQ==", + "version": "0.2003.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2003.25.tgz", + "integrity": "sha512-39pTqt4wSmpD1WeCee46oSGXRh6TR1PFd9GZEwyZoMvBTMs8mE2sXGxUgd4Qyi5CkQ1XnCM5XfgJcjUWUQRoGg==", "requires": { - "@angular-devkit/core": "20.3.20", + "@angular-devkit/core": "20.3.25", "rxjs": "7.8.2" }, "dependencies": { "@angular-devkit/core": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.20.tgz", - "integrity": "sha512-Iobw7He3yJVR2aQ6JN9Kq/2ldD8+uHzJZwd41SQ91A+TzPrBRSV0t80WHHrANZ7xnAjtHDc7zSSGp/i7DzUc9g==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.25.tgz", + "integrity": "sha512-pSfeWEoS1y9zxqTOw0Etj2NXkRmp/aU52wdnyq3KqVA9cJtgxtlOHlBBNswTil4dReojEy+0K1xJm+mLuWuLxA==", "requires": { "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "rxjs": "7.8.2", "source-map": "0.7.6" } @@ -18250,32 +19042,15 @@ "ajv": "^8.0.0" } }, - "chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "optional": true, - "peer": true, - "requires": { - "readdirp": "^4.0.1" - } - }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==" - }, - "readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "optional": true, - "peer": true + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" }, "source-map": { "version": "0.7.6", @@ -18285,15 +19060,15 @@ } }, "@angular-devkit/build-angular": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.3.20.tgz", - "integrity": "sha512-ihBD8zsRoMsuwS3KkwqwwlJGw5jcLerG8zy1kdSEsdJwIYjITgMdV+iK02uSWptLTDd3ILOdgcoZzipcEwJX4w==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.3.25.tgz", + "integrity": "sha512-jp2sbJhbVRT65RbGENY/lz3Z0W0D50Af3xzENmLDLBVp9uhlpIPSTC9LG4CEPV7T6H5Oq6ymHKM+OO5WwTlHHA==", "requires": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2003.20", - "@angular-devkit/build-webpack": "0.2003.20", - "@angular-devkit/core": "20.3.20", - "@angular/build": "20.3.20", + "@angular-devkit/architect": "0.2003.25", + "@angular-devkit/build-webpack": "0.2003.25", + "@angular-devkit/core": "20.3.25", + "@angular/build": "20.3.25", "@babel/core": "7.28.3", "@babel/generator": "7.28.3", "@babel/helper-annotate-as-pure": "7.27.3", @@ -18304,15 +19079,15 @@ "@babel/preset-env": "7.28.3", "@babel/runtime": "7.28.3", "@discoveryjs/json-ext": "0.6.3", - "@ngtools/webpack": "20.3.20", + "@ngtools/webpack": "20.3.25", "ansi-colors": "4.1.3", "autoprefixer": "10.4.21", "babel-loader": "10.0.0", "browserslist": "^4.21.5", "copy-webpack-plugin": "14.0.0", "css-loader": "7.1.2", - "esbuild": "0.25.9", - "esbuild-wasm": "0.25.9", + "esbuild": "0.28.0", + "esbuild-wasm": "0.28.0", "fast-glob": "3.3.3", "http-proxy-middleware": "3.0.5", "istanbul-lib-instrument": "6.0.3", @@ -18325,9 +19100,9 @@ "mini-css-extract-plugin": "2.9.4", "open": "10.2.0", "ora": "8.2.0", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "piscina": "5.1.3", - "postcss": "8.5.6", + "postcss": "8.5.12", "postcss-loader": "8.1.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.2", @@ -18347,18 +19122,174 @@ }, "dependencies": { "@angular-devkit/core": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.20.tgz", - "integrity": "sha512-Iobw7He3yJVR2aQ6JN9Kq/2ldD8+uHzJZwd41SQ91A+TzPrBRSV0t80WHHrANZ7xnAjtHDc7zSSGp/i7DzUc9g==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.25.tgz", + "integrity": "sha512-pSfeWEoS1y9zxqTOw0Etj2NXkRmp/aU52wdnyq3KqVA9cJtgxtlOHlBBNswTil4dReojEy+0K1xJm+mLuWuLxA==", "requires": { "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "rxjs": "7.8.2", "source-map": "0.7.6" } }, + "@esbuild/aix-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "optional": true + }, + "@esbuild/netbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "optional": true + }, + "@esbuild/openbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "optional": true + }, + "@esbuild/openharmony-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "optional": true + }, "ajv": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", @@ -18378,16 +19309,6 @@ "ajv": "^8.0.0" } }, - "chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "optional": true, - "peer": true, - "requires": { - "readdirp": "^4.0.1" - } - }, "debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -18396,6 +19317,40 @@ "ms": "^2.1.3" } }, + "esbuild": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "optional": true, + "requires": { + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" + } + }, "http-proxy-middleware": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", @@ -18430,16 +19385,9 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==" - }, - "readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "optional": true, - "peer": true + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" }, "semver": { "version": "7.7.2", @@ -18465,20 +19413,20 @@ } }, "@angular-devkit/build-webpack": { - "version": "0.2003.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2003.20.tgz", - "integrity": "sha512-WLeYLFxRnEYwCrPUx8qciWs+PrJKDp71ZsIRqeFCcpB8qFQOgR/CjPZYxZFqAnuTJtM4MqCtczvmn57ulKTPcA==", + "version": "0.2003.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2003.25.tgz", + "integrity": "sha512-jJMpYBdWeRfvrCna7JWsyMBbvjMcPblyzh4/pSfWw5znla3hJGzDtmb84qKZ+IB8eZNEcky4iGR5LK2jdGFLAg==", "requires": { - "@angular-devkit/architect": "0.2003.20", + "@angular-devkit/architect": "0.2003.25", "rxjs": "7.8.2" } }, "@angular-devkit/schematics": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.20.tgz", - "integrity": "sha512-+NNHQhQHcgQWZopStZ6os30YuP99lRzNS4wOnkJmoROy40SZct8lPnl2QW50a9Vc0AtaHx1a1NUZ+ohbf6fXqw==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.25.tgz", + "integrity": "sha512-IB0IHf8ZRqr69hT/XIfHkYLPAYHWQ/WUc6+fKHBwq58jJlm/y5QUeTEuXvJ18IX/+hUIqw+E2Q3T0N9rLDLzXg==", "requires": { - "@angular-devkit/core": "20.3.20", + "@angular-devkit/core": "20.3.25", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "8.2.0", @@ -18486,14 +19434,14 @@ }, "dependencies": { "@angular-devkit/core": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.20.tgz", - "integrity": "sha512-Iobw7He3yJVR2aQ6JN9Kq/2ldD8+uHzJZwd41SQ91A+TzPrBRSV0t80WHHrANZ7xnAjtHDc7zSSGp/i7DzUc9g==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.25.tgz", + "integrity": "sha512-pSfeWEoS1y9zxqTOw0Etj2NXkRmp/aU52wdnyq3KqVA9cJtgxtlOHlBBNswTil4dReojEy+0K1xJm+mLuWuLxA==", "requires": { "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "rxjs": "7.8.2", "source-map": "0.7.6" } @@ -18517,32 +19465,15 @@ "ajv": "^8.0.0" } }, - "chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "optional": true, - "peer": true, - "requires": { - "readdirp": "^4.0.1" - } - }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==" - }, - "readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "optional": true, - "peer": true + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" }, "source-map": { "version": "0.7.6", @@ -18552,20 +19483,20 @@ } }, "@angular/animations": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.18.tgz", - "integrity": "sha512-XFxgSyjfs0SRD2vQVFJljmM4z9nTvUoI8TRqSre/+l8D2FgzD5pG67Aj2BgDgpSFAUkIcI37G48ijK7a3ZZ3WA==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.19.tgz", + "integrity": "sha512-/FjU9i7J58/yBURhgVSIiLDcuyOfJxAa0b7ZrOsx6P+FES+M2T2BKZl5V2NuiP2fDFtjsV7U+M/Z9UNUmeHCEw==", "requires": { "tslib": "^2.3.0" } }, "@angular/build": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.3.20.tgz", - "integrity": "sha512-+uWqGU+Qyso2uJKL1xNjAm+E3m3ncv5InMUG5BC/UhFnXTsL1o7oySGc6hHa+8rQunuifUhdy20HxZjU6QlqTw==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.3.25.tgz", + "integrity": "sha512-ddWmPzYuzDWz9ql0262u9w3OJHXpSjHVNIDFIYOG2XYyMj/Xve0RkJ8/xvV+Hv7T3iqyyGKtsO+n/d0GCJQCtQ==", "requires": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2003.20", + "@angular-devkit/architect": "0.2003.25", "@babel/core": "7.28.3", "@babel/helper-annotate-as-pure": "7.27.3", "@babel/helper-split-export-declaration": "7.24.7", @@ -18573,7 +19504,7 @@ "@vitejs/plugin-basic-ssl": "2.1.0", "beasties": "0.3.5", "browserslist": "^4.23.0", - "esbuild": "0.25.9", + "esbuild": "0.28.0", "https-proxy-agent": "7.0.6", "istanbul-lib-instrument": "6.0.3", "jsonc-parser": "3.3.1", @@ -18582,17 +19513,173 @@ "magic-string": "0.30.17", "mrmime": "2.0.1", "parse5-html-rewriting-stream": "8.0.0", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "piscina": "5.1.3", "rollup": "4.59.0", "sass": "1.90.0", "semver": "7.7.2", "source-map-support": "0.5.21", "tinyglobby": "0.2.14", - "vite": "7.1.11", + "vite": "7.3.2", "watchpack": "2.4.4" }, "dependencies": { + "@esbuild/aix-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "optional": true + }, + "@esbuild/netbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "optional": true + }, + "@esbuild/openbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "optional": true + }, + "@esbuild/openharmony-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "optional": true + }, "ansi-escapes": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", @@ -18633,6 +19720,39 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==" }, + "esbuild": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "requires": { + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" + } + }, "eventemitter3": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", @@ -18696,9 +19816,9 @@ } }, "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==" }, "restore-cursor": { "version": "5.1.0", @@ -18759,17 +19879,17 @@ } }, "@angular/cli": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.3.20.tgz", - "integrity": "sha512-wHMo0BWhoBMXcsZ1U+yJ0eOH2B5NgCWW7PTrJ1P/QbocbCSh7eqw8wKnEthIKyhrEWtAo67Jw7i8CgbeIZgmMw==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.3.25.tgz", + "integrity": "sha512-QOSxza45CZY11kqPVpqsU+WGYF99rR/r9A9GykZQWuAHb5SEAxlXHyaaGMu/BMtBHy5HNIlJH25UlzelrbaNyQ==", "requires": { - "@angular-devkit/architect": "0.2003.20", - "@angular-devkit/core": "20.3.20", - "@angular-devkit/schematics": "20.3.20", + "@angular-devkit/architect": "0.2003.25", + "@angular-devkit/core": "20.3.25", + "@angular-devkit/schematics": "20.3.25", "@inquirer/prompts": "7.8.2", "@listr2/prompt-adapter-inquirer": "3.0.1", "@modelcontextprotocol/sdk": "1.26.0", - "@schematics/angular": "20.3.20", + "@schematics/angular": "20.3.25", "@yarnpkg/lockfile": "1.1.0", "algoliasearch": "5.35.0", "ini": "5.0.0", @@ -18784,14 +19904,14 @@ }, "dependencies": { "@angular-devkit/core": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.20.tgz", - "integrity": "sha512-Iobw7He3yJVR2aQ6JN9Kq/2ldD8+uHzJZwd41SQ91A+TzPrBRSV0t80WHHrANZ7xnAjtHDc7zSSGp/i7DzUc9g==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.25.tgz", + "integrity": "sha512-pSfeWEoS1y9zxqTOw0Etj2NXkRmp/aU52wdnyq3KqVA9cJtgxtlOHlBBNswTil4dReojEy+0K1xJm+mLuWuLxA==", "requires": { "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "rxjs": "7.8.2", "source-map": "0.7.6" } @@ -18841,16 +19961,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==" }, - "chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "optional": true, - "peer": true, - "requires": { - "readdirp": "^4.0.1" - } - }, "cli-cursor": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", @@ -18941,16 +20051,9 @@ } }, "picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==" - }, - "readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "optional": true, - "peer": true + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" }, "restore-cursor": { "version": "5.1.0", @@ -19016,25 +20119,25 @@ } }, "@angular/common": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.18.tgz", - "integrity": "sha512-M62oQbSTRmnGavIVCwimoadg/PDWadgNhactMm9fgH0eM9rx+iWBAYJk4VufO0bwOhysFpRZpJgXlFjOifz/Jw==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.19.tgz", + "integrity": "sha512-hcB1eUEN8LGcKGc4DlRJ+abS6AYfbEHDZKg8LnXNugkbwI6Ebyh2AUYTDhzZL2S4aH+C8biHKgSYHFCqieCRhA==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.18.tgz", - "integrity": "sha512-AaP/LCiDNcYmF135EEozjyR04NRBT38ZfBHQwjhgwiBBTejmvcpHwJaHSkraLpZqZzE4BQqqmgiQ1EJqxEwLVA==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.19.tgz", + "integrity": "sha512-ETkgDKm0l2PuaBubgPJe0ccy8kE75DFu6/zKcz7TUuk3KrKF2OZAopbbjftsUSZGeCNvCdqHzjmcL6hQ6oAOwA==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler-cli": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.18.tgz", - "integrity": "sha512-zsoEgLgnblmRbi47YwMghKirJ8IBKJ3+I8TxLBRIBrhx+KHFp+6oeDeLyu9H+djdyk88zexVd09wzR/YK73F0g==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.19.tgz", + "integrity": "sha512-ET/JjO8s62kAHfgIsGXlvW5VUwLqHm03q1y/2yD7aQW/WdDvssMsvZv7Knl440989vdOFemIGTMwVPakmWqRmA==", "requires": { "@babel/core": "7.28.3", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -19062,31 +20165,31 @@ } }, "@angular/core": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.18.tgz", - "integrity": "sha512-B+NQQngd/aDbcfW0zGLis3wTLDeHTeTYMl/mGKQH+HwdPaRCKI1wEtaXaOYVJXkP2FeThocPevB8gLwNlPQUUw==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.19.tgz", + "integrity": "sha512-SYnwW+q51bQoPtGFoGovm1P5GK9fMEXsG0lGaEAUapjskblAYyX7hLlM/jgueSojv2SjhqNF8aXR+gjHLhZVNA==", "requires": { "tslib": "^2.3.0" } }, "@angular/forms": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.18.tgz", - "integrity": "sha512-x6/99LfxolyZIFUL3Wr0OrtuXHEDwEz/rwx+WzE7NL+n35yO40t3kp0Sn5uMFwI94i91QZJmXHltMpZhrVLuYg==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.19.tgz", + "integrity": "sha512-WJotd+Lhl4FG2b0K+aQNyQDHhR515zKCuphjiUqEW7sifWrOQxANLKzPBngGrH75ayANFgPaDf7U3ZRIoblcQA==", "requires": { "tslib": "^2.3.0" } }, "@angular/language-service": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-20.3.18.tgz", - "integrity": "sha512-V1ZBqeTtZYH9H8/G1qCw6gafsJmhMIMFjLX0Hv2KpTpmfK9nxIHPEVnshr3xT+qKYJIrMV/cU5YOzInEapLpuQ==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-20.3.19.tgz", + "integrity": "sha512-9J0XrAKXInz11KKyNMrMZmn2NSjVbxzt/DsAumbrzzixeZwiY7vDy2Kqw/LLFLi7IlfMQ/gznz/mCVVgUWI5Gg==", "dev": true }, "@angular/localize": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-20.3.18.tgz", - "integrity": "sha512-Zx7LiyMjTvooPhy/r6RoyWzGECfWiA8jH4zwsa/xPF6RX8MD/hOi8vcS4UxTdLSWB4lM5ZtSifAnOfwcm/0CyQ==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-20.3.19.tgz", + "integrity": "sha512-bXOwxzJUvHzmADI6czdjYnuBMil/UK3CW1dfbrC1MrlLtD0R7g4YZs08J7aWXd+/A4LmTPfkpZhI5ApxGAL0Tg==", "requires": { "@babel/core": "7.28.3", "@types/babel__core": "7.20.5", @@ -19095,42 +20198,42 @@ } }, "@angular/platform-browser": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.18.tgz", - "integrity": "sha512-q6s5rEN1yYazpHYp+k4pboXRzMsRB9auzTRBEhyXSGYxqzrnn3qHN0DqgsLC9WAdyhCgnIEMFA8kRT+W277DqQ==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.19.tgz", + "integrity": "sha512-TRZfatH1B/kreDwFRwtpLEurJQ6044qh6DWpvxzTbugaG5otLQJKTk+1z81/KsJwQqc1+24v+yuywc1LM7aq7w==", "requires": { "tslib": "^2.3.0" } }, "@angular/platform-browser-dynamic": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.18.tgz", - "integrity": "sha512-NyTobOGYVzGmPmtI+3lxMzxi0TbLq4SRNQ2ENEJAt6k2JnMmHBm483ppLRAM47nGlDdiraW0IX93EtYYNkiK3g==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.19.tgz", + "integrity": "sha512-OgErw7wjcC+8yKF5h99hJq8x+tvc091wThfmdL5YC+U3HgRmUaNZFgB/jR7cb/NeeeC42QW5Vc0qoUTC9rMnLQ==", "requires": { "tslib": "^2.3.0" } }, "@angular/platform-server": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-20.3.18.tgz", - "integrity": "sha512-iw4QSmEWEKbyMT5u8QdhalNiPqRc7cRuo6lulU75pjXqVLwLb3Gq8it+Vo+LSKY6qI/bMO7olS7iyw09wXJ0OQ==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-20.3.19.tgz", + "integrity": "sha512-9STNB8Z5uYpaIgzfiJOH81c4CY2lM3oq/650+pdnjJsedxyEi+NAbnn5tF857Cd/N+43lR+OMolKgm0MJziHqw==", "requires": { "tslib": "^2.3.0", "xhr2": "^0.2.0" } }, "@angular/router": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.18.tgz", - "integrity": "sha512-3CWejsEYr+ze+ktvWN/qHdyq5WLrj96QZpGYJyxh1pchIcpMPE9MmLpdjf0CUrWYB7g/85u0Geq/xsz72JrGng==", + "version": "20.3.19", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.19.tgz", + "integrity": "sha512-qHrMniHOsCJ4neZmcQVodjutJilyXAXk7EhLa931QyL0qyVKVomv6E0I3UFzRaC3ZeHc+hzBdU6C6bvMFKTl1g==", "requires": { "tslib": "^2.3.0" } }, "@angular/ssr": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-20.3.20.tgz", - "integrity": "sha512-DA/rp8BoaBAOQmRVd2+zgvJilrwmv60CVidC8bf9aF0oURQyD/LpcTAaGKrGf4DEoulsXdDvKEI+WN7oUJs56A==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-20.3.25.tgz", + "integrity": "sha512-A/lbXQ+GucLAQfCJ5img7/xuqlftWjJU+iJABq/ARDkOOE/rNHrxFkXjJBntj97+oXjr7HBYI2sxYRZCCEiEag==", "requires": { "tslib": "^2.3.0" } @@ -20224,159 +21327,159 @@ "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==" }, "@esbuild/aix-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", - "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", "optional": true }, "@esbuild/android-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", - "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", "optional": true }, "@esbuild/android-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", - "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", "optional": true }, "@esbuild/android-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", - "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", - "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", "optional": true }, "@esbuild/darwin-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", - "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", - "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", - "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", "optional": true }, "@esbuild/linux-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", - "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", "optional": true }, "@esbuild/linux-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", - "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", "optional": true }, "@esbuild/linux-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", - "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", "optional": true }, "@esbuild/linux-loong64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", - "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", - "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", - "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", - "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", "optional": true }, "@esbuild/linux-s390x": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", - "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", "optional": true }, "@esbuild/linux-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", - "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", "optional": true }, "@esbuild/netbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", - "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", - "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", "optional": true }, "@esbuild/openbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", - "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", - "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", "optional": true }, "@esbuild/openharmony-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", - "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", "optional": true }, "@esbuild/sunos-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", - "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", "optional": true }, "@esbuild/win32-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", - "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", "optional": true }, "@esbuild/win32-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", - "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", "optional": true }, "@esbuild/win32-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", - "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", "optional": true }, "@eslint-community/eslint-utils": { @@ -21325,9 +22428,9 @@ } }, "@ngtools/webpack": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.3.20.tgz", - "integrity": "sha512-5azJ9+W/aMFR4C38ShoWib6xW5ou5Q5yeup+6skpvrud5mAAj3e36S5diYYXqbzVfo3DM+sWueDRNP3DV7IHhg==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.3.25.tgz", + "integrity": "sha512-p/YopAgukaIvezv3hsJzJevnNUBNTM8UQIkyDHPY5/aANdKraUTKDQUwlVxRiyD8U+PTSeD/BI56oOnuKrdFZQ==", "requires": {} }, "@noble/secp256k1": { @@ -21793,24 +22896,24 @@ "optional": true }, "@schematics/angular": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.3.20.tgz", - "integrity": "sha512-LyoHwenNi8lZZO5zafAjcN8DcaOdjFrkbZdrCkvdpmOFz5wy8ZGchY6XSZEDD6kdHvR8oU7WWnGTMgCfExBKCg==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.3.25.tgz", + "integrity": "sha512-ezoJpPKhhjXgE3LxuNcJO/ghSXs8f73xrqGvqouag7IbuliJYbHrt22WH3X75XSbD0+iOdiqA2bARvAO/ezyxQ==", "requires": { - "@angular-devkit/core": "20.3.20", - "@angular-devkit/schematics": "20.3.20", + "@angular-devkit/core": "20.3.25", + "@angular-devkit/schematics": "20.3.25", "jsonc-parser": "3.3.1" }, "dependencies": { "@angular-devkit/core": { - "version": "20.3.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.20.tgz", - "integrity": "sha512-Iobw7He3yJVR2aQ6JN9Kq/2ldD8+uHzJZwd41SQ91A+TzPrBRSV0t80WHHrANZ7xnAjtHDc7zSSGp/i7DzUc9g==", + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.25.tgz", + "integrity": "sha512-pSfeWEoS1y9zxqTOw0Etj2NXkRmp/aU52wdnyq3KqVA9cJtgxtlOHlBBNswTil4dReojEy+0K1xJm+mLuWuLxA==", "requires": { "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "rxjs": "7.8.2", "source-map": "0.7.6" } @@ -21834,32 +22937,15 @@ "ajv": "^8.0.0" } }, - "chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "optional": true, - "peer": true, - "requires": { - "readdirp": "^4.0.1" - } - }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==" - }, - "readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "optional": true, - "peer": true + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" }, "source-map": { "version": "0.7.6", @@ -24382,42 +25468,42 @@ } }, "esbuild": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", - "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", "requires": { - "@esbuild/aix-ppc64": "0.25.9", - "@esbuild/android-arm": "0.25.9", - "@esbuild/android-arm64": "0.25.9", - "@esbuild/android-x64": "0.25.9", - "@esbuild/darwin-arm64": "0.25.9", - "@esbuild/darwin-x64": "0.25.9", - "@esbuild/freebsd-arm64": "0.25.9", - "@esbuild/freebsd-x64": "0.25.9", - "@esbuild/linux-arm": "0.25.9", - "@esbuild/linux-arm64": "0.25.9", - "@esbuild/linux-ia32": "0.25.9", - "@esbuild/linux-loong64": "0.25.9", - "@esbuild/linux-mips64el": "0.25.9", - "@esbuild/linux-ppc64": "0.25.9", - "@esbuild/linux-riscv64": "0.25.9", - "@esbuild/linux-s390x": "0.25.9", - "@esbuild/linux-x64": "0.25.9", - "@esbuild/netbsd-arm64": "0.25.9", - "@esbuild/netbsd-x64": "0.25.9", - "@esbuild/openbsd-arm64": "0.25.9", - "@esbuild/openbsd-x64": "0.25.9", - "@esbuild/openharmony-arm64": "0.25.9", - "@esbuild/sunos-x64": "0.25.9", - "@esbuild/win32-arm64": "0.25.9", - "@esbuild/win32-ia32": "0.25.9", - "@esbuild/win32-x64": "0.25.9" + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" } }, "esbuild-wasm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.9.tgz", - "integrity": "sha512-Jpv5tCSwQg18aCqCRD3oHIX/prBhXMDapIoG//A+6+dV0e7KQMGFg85ihJ5T1EeMjbZjON3TqFy0VrGAnIHLDA==" + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.28.0.tgz", + "integrity": "sha512-5TRVKExcEmeMkccIZMzUq+Az6X2RoMAJyfl6SMMO1dMVhmvt0I2mx7gAb6zYi42n4d1ETcatFXazGKzA+aW7fg==" }, "escalade": { "version": "3.2.0", @@ -27376,9 +28462,9 @@ } }, "postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.12.tgz", + "integrity": "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==", "requires": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -28990,11 +30076,11 @@ } }, "vite": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.11.tgz", - "integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", + "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", "requires": { - "esbuild": "^0.25.0", + "esbuild": "^0.27.0", "fdir": "^6.5.0", "fsevents": "~2.3.3", "picomatch": "^4.0.3", diff --git a/frontend/package.json b/frontend/package.json index d134d8e1a..06b57905b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -59,19 +59,19 @@ "cypress:run:ci:parameterized": "node update-config.js TESTNET_ENABLED=true TESTNET4_ENABLED=true SIGNET_ENABLED=true LIQUID_ENABLED=true ITEMS_PER_PAGE=25 && npm run generate-config && start-server-and-test serve:parameterized 4200 cypress:run:record" }, "dependencies": { - "@angular-devkit/build-angular": "^20.3.20", - "@angular/animations": "^20.3.18", - "@angular/cli": "^20.3.20", - "@angular/common": "^20.3.18", - "@angular/compiler": "^20.3.18", - "@angular/core": "^20.3.18", - "@angular/forms": "^20.3.18", - "@angular/localize": "^20.3.18", - "@angular/platform-browser": "^20.3.18", - "@angular/platform-browser-dynamic": "^20.3.18", - "@angular/platform-server": "^20.3.18", - "@angular/router": "^20.3.18", - "@angular/ssr": "^20.3.18", + "@angular-devkit/build-angular": "^20.3.25", + "@angular/animations": "^20.3.19", + "@angular/cli": "^20.3.25", + "@angular/common": "^20.3.19", + "@angular/compiler": "^20.3.19", + "@angular/core": "^20.3.19", + "@angular/forms": "^20.3.19", + "@angular/localize": "^20.3.19", + "@angular/platform-browser": "^20.3.19", + "@angular/platform-browser-dynamic": "^20.3.19", + "@angular/platform-server": "^20.3.19", + "@angular/router": "^20.3.19", + "@angular/ssr": "^20.3.25", "@fortawesome/angular-fontawesome": "^3.0.0", "@fortawesome/fontawesome-common-types": "~6.7.2", "@fortawesome/fontawesome-svg-core": "~6.7.2", @@ -91,8 +91,8 @@ "zone.js": "~0.15.1" }, "devDependencies": { - "@angular/compiler-cli": "^20.3.18", - "@angular/language-service": "^20.3.18", + "@angular/compiler-cli": "^20.3.19", + "@angular/language-service": "^20.3.19", "@types/node": "^24.9.2", "@typescript-eslint/eslint-plugin": "^8.46.2", "@typescript-eslint/parser": "^8.46.2", From 39b51c7a7d86b879e75dcb083016fcda0cbb5a1e Mon Sep 17 00:00:00 2001 From: mononaut Date: Mon, 11 May 2026 06:47:06 +0000 Subject: [PATCH 14/17] bump misc frontend dependencies --- frontend/package-lock.json | 532 +++++++++++++++++++++---------------- 1 file changed, 296 insertions(+), 236 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 06ebe6778..0f0b850c0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2815,12 +2815,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -3076,27 +3076,27 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -3118,9 +3118,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -3239,12 +3239,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -3787,15 +3787,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", - "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", + "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.5" + "@babel/traverse": "^7.29.0" }, "engines": { "node": ">=6.9.0" @@ -4341,31 +4341,31 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { @@ -4373,13 +4373,13 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -4399,9 +4399,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -5192,9 +5192,10 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.10", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.10.tgz", - "integrity": "sha512-hZ7nOssGqRgyV3FVVQdfi+U4q02uB23bpnYpdvNXkYTRRyWx84b7yf1ans+dnJ/7h41sGL3CeQTfO+ZGxuO+Iw==", + "version": "1.19.14", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", + "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "license": "MIT", "engines": { "node": ">=18.14.1" }, @@ -7900,9 +7901,10 @@ } }, "node_modules/@tufjs/models/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, @@ -8402,10 +8404,11 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "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" }, @@ -9037,22 +9040,26 @@ "optional": true }, "node_modules/axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", + "license": "MIT", "optional": true, "dependencies": { - "follow-redirects": "^1.15.11", + "follow-redirects": "^1.16.0", "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" + "proxy-from-env": "^2.1.0" } }, "node_modules/axios/node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", - "optional": true + "optional": true, + "engines": { + "node": ">=10" + } }, "node_modules/babel-loader": { "version": "10.0.0", @@ -9376,9 +9383,9 @@ } }, "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.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "devOptional": true, "license": "MIT", "dependencies": { @@ -10303,15 +10310,6 @@ "node": ">=10.13.0" } }, - "node_modules/copy-webpack-plugin/node_modules/serialize-javascript": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.4.tgz", - "integrity": "sha512-DuGdB+Po43Q5Jxwpzt1lhyFSYKryqoNjQSA9M92tyw0lyHIOur+XCalOUe0KTJpyqzT8+fQ5A0Jf7vCx/NKmIg==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=20.0.0" - } - }, "node_modules/core-js-compat": { "version": "3.46.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz", @@ -11717,9 +11715,10 @@ } }, "node_modules/express-rate-limit": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", - "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.4.1.tgz", + "integrity": "sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQCm+rFvLsBH6w4xcXWTcliS8La5EPRN3p9wzItqBwJrfNw==", + "license": "MIT", "dependencies": { "ip-address": "10.1.0" }, @@ -12270,15 +12269,16 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -12532,9 +12532,10 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, @@ -12704,9 +12705,10 @@ } }, "node_modules/hono": { - "version": "4.12.7", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz", - "integrity": "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw==", + "version": "4.12.16", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.16.tgz", + "integrity": "sha512-jN0ZewiNAWSe5khM3EyCmBb250+b40wWbwNILNfEvq84VREWwOIkuUsFONk/3i3nqkz7Oe1PcpM2mwQEK2L9Kg==", + "license": "MIT", "engines": { "node": ">=16.9.0" } @@ -12995,9 +12997,10 @@ } }, "node_modules/ignore-walk/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, @@ -13857,10 +13860,11 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", - "devOptional": true + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "devOptional": true, + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", @@ -14590,9 +14594,10 @@ "optional": true }, "node_modules/node-forge": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", - "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", + "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" } @@ -15411,9 +15416,9 @@ } }, "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", @@ -15458,9 +15463,10 @@ "license": "ISC" }, "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==", + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -16561,6 +16567,15 @@ "node": ">= 0.8" } }, + "node_modules/serialize-javascript": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -16902,18 +16917,44 @@ } }, "node_modules/socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", + "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", "devOptional": true, + "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" + "debug": "~4.4.1" }, "engines": { "node": ">=10.0.0" } }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "devOptional": true, + "license": "MIT" + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -17465,9 +17506,9 @@ } }, "node_modules/tinyglobby/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==", "license": "MIT", "engines": { "node": ">=12" @@ -18031,9 +18072,10 @@ } }, "node_modules/vite/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==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -18380,9 +18422,10 @@ } }, "node_modules/webpack-dev-server/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/webpack-dev-server/node_modules/statuses": { "version": "2.0.2", @@ -20239,11 +20282,11 @@ } }, "@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "requires": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } @@ -20430,22 +20473,22 @@ } }, "@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "requires": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" } }, "@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "requires": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" } }, "@babel/helper-optimise-call-expression": { @@ -20457,9 +20500,9 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==" + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==" }, "@babel/helper-remap-async-to-generator": { "version": "7.27.1", @@ -20533,11 +20576,11 @@ } }, "@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", "requires": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.0" } }, "@babel/plugin-bugfix-firefox-class-in-computed-class-key": { @@ -20837,14 +20880,14 @@ } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", - "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", + "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", "requires": { - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.5" + "@babel/traverse": "^7.29.0" } }, "@babel/plugin-transform-modules-umd": { @@ -21183,36 +21226,36 @@ "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==" }, "@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "requires": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" } }, "@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "requires": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "dependencies": { "@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "requires": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -21230,9 +21273,9 @@ } }, "@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "requires": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" @@ -21661,9 +21704,9 @@ } }, "@hono/node-server": { - "version": "1.19.10", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.10.tgz", - "integrity": "sha512-hZ7nOssGqRgyV3FVVQdfi+U4q02uB23bpnYpdvNXkYTRRyWx84b7yf1ans+dnJ/7h41sGL3CeQTfO+ZGxuO+Iw==", + "version": "1.19.14", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", + "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", "requires": {} }, "@humanfs/core": { @@ -23113,9 +23156,9 @@ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==" }, "brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "requires": { "balanced-match": "^4.0.2" } @@ -23505,9 +23548,9 @@ "dev": true }, "brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "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, "requires": { "balanced-match": "^4.0.2" @@ -23949,20 +23992,20 @@ "optional": true }, "axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", "optional": true, "requires": { - "follow-redirects": "^1.15.11", + "follow-redirects": "^1.16.0", "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" + "proxy-from-env": "^2.1.0" }, "dependencies": { "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "optional": true } } @@ -24190,9 +24233,9 @@ "requires": {} }, "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.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "devOptional": true, "requires": { "balanced-match": "^1.0.0", @@ -24833,11 +24876,6 @@ "requires": { "is-glob": "^4.0.3" } - }, - "serialize-javascript": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.4.tgz", - "integrity": "sha512-DuGdB+Po43Q5Jxwpzt1lhyFSYKryqoNjQSA9M92tyw0lyHIOur+XCalOUe0KTJpyqzT8+fQ5A0Jf7vCx/NKmIg==" } } }, @@ -26003,9 +26041,9 @@ } }, "express-rate-limit": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", - "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.4.1.tgz", + "integrity": "sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQCm+rFvLsBH6w4xcXWTcliS8La5EPRN3p9wzItqBwJrfNw==", "requires": { "ip-address": "10.1.0" } @@ -26207,9 +26245,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==" + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==" }, "forever-agent": { "version": "0.6.1", @@ -26348,9 +26386,9 @@ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==" }, "brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "requires": { "balanced-match": "^4.0.2" } @@ -26482,9 +26520,9 @@ } }, "hono": { - "version": "4.12.7", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz", - "integrity": "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw==" + "version": "4.12.16", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.16.tgz", + "integrity": "sha512-jN0ZewiNAWSe5khM3EyCmBb250+b40wWbwNILNfEvq84VREWwOIkuUsFONk/3i3nqkz7Oe1PcpM2mwQEK2L9Kg==" }, "hosted-git-info": { "version": "9.0.2", @@ -26688,9 +26726,9 @@ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==" }, "brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "requires": { "balanced-match": "^4.0.2" } @@ -27265,9 +27303,9 @@ } }, "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==", "devOptional": true }, "lodash.debounce": { @@ -27820,9 +27858,9 @@ "optional": true }, "node-forge": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", - "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==" }, "node-gyp": { "version": "12.2.0", @@ -28375,9 +28413,9 @@ } }, "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==" }, "pathval": { "version": "1.1.1", @@ -28412,9 +28450,9 @@ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "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==" }, "pify": { "version": "2.3.0", @@ -29134,6 +29172,11 @@ } } }, + "serialize-javascript": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==" + }, "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -29395,13 +29438,30 @@ } }, "socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", + "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", "devOptional": true, "requires": { "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" + "debug": "~4.4.1" + }, + "dependencies": { + "debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "devOptional": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "devOptional": true + } } }, "sockjs": { @@ -29769,9 +29829,9 @@ "requires": {} }, "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==" } } }, @@ -30096,9 +30156,9 @@ "requires": {} }, "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==" }, "tinyglobby": { "version": "0.2.15", @@ -30361,9 +30421,9 @@ } }, "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==" }, "statuses": { "version": "2.0.2", From 34d4b7fa6fbdc25c98bee9f5a2f5f57e5f05a868 Mon Sep 17 00:00:00 2001 From: hunicus <93150691+hunicus@users.noreply.github.com> Date: Mon, 11 May 2026 05:19:36 -0400 Subject: [PATCH 15/17] Add bdk svg with text --- .../app/components/about/about.component.html | 4 +- .../src/resources/profile/bdk-simple-logo.svg | 31 ---------- frontend/src/resources/profile/bdk.svg | 56 +++++++++++++++++++ 3 files changed, 58 insertions(+), 33 deletions(-) delete mode 100644 frontend/src/resources/profile/bdk-simple-logo.svg create mode 100644 frontend/src/resources/profile/bdk.svg diff --git a/frontend/src/app/components/about/about.component.html b/frontend/src/app/components/about/about.component.html index 5fbcc69cc..2a024d374 100644 --- a/frontend/src/app/components/about/about.component.html +++ b/frontend/src/app/components/about/about.component.html @@ -433,8 +433,8 @@
- diff --git a/frontend/src/resources/profile/bdk-simple-logo.svg b/frontend/src/resources/profile/bdk-simple-logo.svg deleted file mode 100644 index 57c164326..000000000 --- a/frontend/src/resources/profile/bdk-simple-logo.svg +++ /dev/null @@ -1,31 +0,0 @@ - - - BDK Simple Logo + Foundation - - - - - - - - - - - - - - - - BDK - Foundation - - diff --git a/frontend/src/resources/profile/bdk.svg b/frontend/src/resources/profile/bdk.svg new file mode 100644 index 000000000..54e68b634 --- /dev/null +++ b/frontend/src/resources/profile/bdk.svg @@ -0,0 +1,56 @@ + + + + From 4a7b63dd6f367b32e4f5785d591fb3aa5c442e07 Mon Sep 17 00:00:00 2001 From: nymkappa Date: Wed, 13 May 2026 14:52:32 +0200 Subject: [PATCH 16/17] [about] tweak breakpoints with new bdk logo --- frontend/src/app/components/about/about.component.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/components/about/about.component.html b/frontend/src/app/components/about/about.component.html index 2a024d374..c93e831c9 100644 --- a/frontend/src/app/components/about/about.component.html +++ b/frontend/src/app/components/about/about.component.html @@ -409,7 +409,7 @@

Community Alliances

- + - + - + - + From d11dbc61ff677e997513dea9ed2e6665eb4652ff Mon Sep 17 00:00:00 2001 From: nymkappa Date: Fri, 15 May 2026 07:10:38 +0200 Subject: [PATCH 17/17] [npm] fix unsynced package-lock --- frontend/package-lock.json | 245 +++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 0f0b850c0..31efabc31 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -354,6 +354,23 @@ } } }, + "node_modules/@angular-devkit/architect/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/architect/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -372,6 +389,21 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/@angular-devkit/architect/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/architect/node_modules/source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", @@ -989,6 +1021,23 @@ } } }, + "node_modules/@angular-devkit/build-angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/build-angular/node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -1107,6 +1156,21 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/@angular-devkit/build-angular/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/build-angular/node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -1243,6 +1307,23 @@ } } }, + "node_modules/@angular-devkit/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/schematics/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -1261,6 +1342,21 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/@angular-devkit/schematics/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/schematics/node_modules/source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", @@ -2282,6 +2378,23 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/@angular/cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/cli/node_modules/cli-cursor": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", @@ -2437,6 +2550,21 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/@angular/cli/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/cli/node_modules/restore-cursor": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", @@ -7688,6 +7816,23 @@ } } }, + "node_modules/@schematics/angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@schematics/angular/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -7706,6 +7851,21 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/@schematics/angular/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@schematics/angular/node_modules/source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", @@ -19085,6 +19245,16 @@ "ajv": "^8.0.0" } }, + "chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "optional": true, + "peer": true, + "requires": { + "readdirp": "^4.0.1" + } + }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -19095,6 +19265,13 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" }, + "readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "optional": true, + "peer": true + }, "source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", @@ -19352,6 +19529,16 @@ "ajv": "^8.0.0" } }, + "chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "optional": true, + "peer": true, + "requires": { + "readdirp": "^4.0.1" + } + }, "debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -19432,6 +19619,13 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" }, + "readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "optional": true, + "peer": true + }, "semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -19508,6 +19702,16 @@ "ajv": "^8.0.0" } }, + "chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "optional": true, + "peer": true, + "requires": { + "readdirp": "^4.0.1" + } + }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -19518,6 +19722,13 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" }, + "readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "optional": true, + "peer": true + }, "source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", @@ -20004,6 +20215,16 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==" }, + "chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "optional": true, + "peer": true, + "requires": { + "readdirp": "^4.0.1" + } + }, "cli-cursor": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", @@ -20098,6 +20319,13 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" }, + "readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "optional": true, + "peer": true + }, "restore-cursor": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", @@ -22980,6 +23208,16 @@ "ajv": "^8.0.0" } }, + "chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "optional": true, + "peer": true, + "requires": { + "readdirp": "^4.0.1" + } + }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -22990,6 +23228,13 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" }, + "readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "optional": true, + "peer": true + }, "source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",