From 855208c14d057a738154da47f1eceeb00f2d6f42 Mon Sep 17 00:00:00 2001 From: shanvit Date: Wed, 1 Apr 2026 13:08:52 +0530 Subject: [PATCH 01/12] feat(skill-reports): add deps, jsx config, template types, monthly-report schema, registry --- packages/skills/reports/package.json | 10 + packages/skills/reports/src/index.ts | 13 +- .../reports/src/templates/monthly-report.ts | 87 ++ .../reports/src/templates/registry.test.ts | 69 + .../skills/reports/src/templates/registry.ts | 43 + .../skills/reports/src/templates/types.ts | 64 + packages/skills/reports/tsconfig.json | 4 +- pnpm-lock.yaml | 1316 ++++++++++++++++- 8 files changed, 1574 insertions(+), 32 deletions(-) create mode 100644 packages/skills/reports/src/templates/monthly-report.ts create mode 100644 packages/skills/reports/src/templates/registry.test.ts create mode 100644 packages/skills/reports/src/templates/registry.ts create mode 100644 packages/skills/reports/src/templates/types.ts diff --git a/packages/skills/reports/package.json b/packages/skills/reports/package.json index d4c1c62..5b0e7de 100644 --- a/packages/skills/reports/package.json +++ b/packages/skills/reports/package.json @@ -15,8 +15,18 @@ "build": "tsc", "check": "tsc --noEmit" }, + "dependencies": { + "@react-pdf/renderer": "^4.3.0", + "@sinclair/typebox": "^0.34.9", + "chart.js": "^4.4.9", + "chartjs-node-canvas": "^4.1.6", + "exceljs": "^4.4.0", + "pptxgenjs": "^3.12.0", + "react": "^19.1.0" + }, "devDependencies": { "@types/node": "^22.15.2", + "@types/react": "^19.1.2", "typescript": "^5.7.3" } } diff --git a/packages/skills/reports/src/index.ts b/packages/skills/reports/src/index.ts index 755e155..9a506ef 100644 --- a/packages/skills/reports/src/index.ts +++ b/packages/skills/reports/src/index.ts @@ -1,3 +1,10 @@ -// Reports Skill - Template-based and agent-generated report creation. -// Implementation in Phase 6. -export {} +// Reports Skill — template-based report generation. +export type { + MonthlyReportData, + RenderOpts, + ReportFormat, + ReportTemplate, + SessionMetricRow, +} from "./templates/types.js" +export { MonthlyReportDataSchema, MonthlyReportTemplate } from "./templates/monthly-report.js" +export { getTemplate, listTemplates, registerTemplate } from "./templates/registry.js" diff --git a/packages/skills/reports/src/templates/monthly-report.ts b/packages/skills/reports/src/templates/monthly-report.ts new file mode 100644 index 0000000..1eb23c5 --- /dev/null +++ b/packages/skills/reports/src/templates/monthly-report.ts @@ -0,0 +1,87 @@ +/** + * Monthly report template — TypeBox schema + render dispatcher. + * + * Renderers (PDF, PPTX, XLSX) are implemented in sibling packages and will + * be wired in once the renderer tasks are merged. Until then, render() stubs + * each format so the registry and tool layer can be built and tested independently. + */ + +import { type Static, Type } from "@sinclair/typebox" +import { Value } from "@sinclair/typebox/value" +import type { MonthlyReportData, RenderOpts, ReportTemplate } from "./types.js" + +// --------------------------------------------------------------------------- +// TypeBox schema +// --------------------------------------------------------------------------- + +const SessionMetricRowSchema = Type.Object({ + sessionId: Type.String(), + messageCount: Type.Number({ minimum: 0 }), + toolCallCount: Type.Number({ minimum: 0 }), + durationSeconds: Type.Number({ minimum: 0 }), +}) + +/** TypeBox schema for {@link MonthlyReportData}. */ +export const MonthlyReportDataSchema = Type.Object({ + period: Type.String({ minLength: 1 }), + totalSessions: Type.Number({ minimum: 0 }), + totalMessages: Type.Number({ minimum: 0 }), + totalToolCalls: Type.Number({ minimum: 0 }), + sessions: Type.Array(SessionMetricRowSchema), +}) + +/** Inferred static type from the TypeBox schema (matches MonthlyReportData). */ +export type MonthlyReportDataSchema = Static + +// --------------------------------------------------------------------------- +// Renderer dispatcher +// --------------------------------------------------------------------------- + +/** + * Dispatch render to the appropriate format renderer. + * Renderer implementations are injected at runtime once the renderer packages + * are available; until then, each branch throws a "not yet implemented" error. + */ +const renderMonthlyReport = async (_data: MonthlyReportData, opts: RenderOpts): Promise => { + switch (opts.format) { + case "pdf": + // TODO: import and call PDF renderer once packages/skills/reports/src/renderers/pdf.tsx is merged + throw new Error("PDF renderer not yet wired — pending renderer task merge") + case "pptx": + // TODO: import and call PPTX renderer once packages/skills/reports/src/renderers/pptx.ts is merged + throw new Error("PPTX renderer not yet wired — pending renderer task merge") + case "xlsx": + // TODO: import and call XLSX renderer once packages/skills/reports/src/renderers/xlsx.ts is merged + throw new Error("XLSX renderer not yet wired — pending renderer task merge") + default: { + // Exhaustiveness check + const _exhaustive: never = opts.format + throw new Error(`Unsupported format: ${String(_exhaustive)}`) + } + } +} + +// --------------------------------------------------------------------------- +// Template definition +// --------------------------------------------------------------------------- + +/** + * Monthly report template. + * Validates input via TypeBox and dispatches rendering to format-specific renderers. + */ +export const MonthlyReportTemplate: ReportTemplate = { + name: "monthly-report", + title: "Monthly Activity Report", + formats: ["pdf", "pptx", "xlsx"], + + parse: (raw: unknown): MonthlyReportData => { + if (!Value.Check(MonthlyReportDataSchema, raw)) { + const errors = [...Value.Errors(MonthlyReportDataSchema, raw)] + const summary = errors.map((e) => `${e.path}: ${e.message}`).join("; ") + throw new Error(`Invalid MonthlyReportData: ${summary}`) + } + return raw as MonthlyReportData + }, + + render: renderMonthlyReport, +} diff --git a/packages/skills/reports/src/templates/registry.test.ts b/packages/skills/reports/src/templates/registry.test.ts new file mode 100644 index 0000000..a9e0ac9 --- /dev/null +++ b/packages/skills/reports/src/templates/registry.test.ts @@ -0,0 +1,69 @@ +/** + * Tests for the template registry. + */ + +import assert from "node:assert/strict" +import { describe, it } from "node:test" +import { getTemplate, listTemplates, registerTemplate } from "./registry.js" +import type { ReportTemplate } from "./types.js" + +describe("template registry", () => { + it("lists built-in monthly-report template", () => { + const templates = listTemplates() + const names = templates.map((t) => t.name) + assert.ok(names.includes("monthly-report"), "monthly-report should be registered by default") + }) + + it("getTemplate returns the monthly-report template", () => { + const tmpl = getTemplate("monthly-report") + assert.ok(tmpl !== undefined, "monthly-report should be found") + assert.equal(tmpl.name, "monthly-report") + assert.equal(tmpl.title, "Monthly Activity Report") + assert.deepEqual(tmpl.formats, ["pdf", "pptx", "xlsx"]) + }) + + it("getTemplate returns undefined for unknown name", () => { + const tmpl = getTemplate("nonexistent-report") + assert.equal(tmpl, undefined) + }) + + it("registerTemplate adds a custom template and it appears in listTemplates", () => { + const custom: ReportTemplate<{ x: number }> = { + name: "custom-test", + title: "Custom Test Report", + formats: ["xlsx"], + parse: (raw) => raw as { x: number }, + render: async (_data, opts) => opts.outputPath, + } + + registerTemplate(custom) + + const found = getTemplate("custom-test") + assert.ok(found !== undefined, "custom template should be found after registration") + assert.equal(found.name, "custom-test") + + const names = listTemplates().map((t) => t.name) + assert.ok(names.includes("custom-test")) + }) + + it("registerTemplate overwrites an existing template with the same name", () => { + const v1: ReportTemplate<{ v: number }> = { + name: "overwrite-test", + title: "Version 1", + formats: ["pdf"], + parse: (raw) => raw as { v: number }, + render: async (_data, opts) => opts.outputPath, + } + const v2: ReportTemplate<{ v: number }> = { + ...v1, + title: "Version 2", + } + + registerTemplate(v1) + registerTemplate(v2) + + const found = getTemplate("overwrite-test") + assert.ok(found !== undefined) + assert.equal(found.title, "Version 2") + }) +}) diff --git a/packages/skills/reports/src/templates/registry.ts b/packages/skills/reports/src/templates/registry.ts new file mode 100644 index 0000000..fce26dc --- /dev/null +++ b/packages/skills/reports/src/templates/registry.ts @@ -0,0 +1,43 @@ +/** + * Template registry — maps template names to ReportTemplate instances. + * + * Built-in templates are registered on module load. Custom templates can be + * added at runtime via {@link registerTemplate}. + */ + +import { MonthlyReportTemplate } from "./monthly-report.js" +import type { ReportTemplate } from "./types.js" + +// biome-ignore lint/suspicious/noExplicitAny: registry stores heterogeneous templates keyed by name +const registry = new Map>() + +/** + * Register a template. If a template with the same name is already registered, + * it will be overwritten. + * + * @param template - The template to register. + */ +export const registerTemplate = (template: ReportTemplate): void => { + registry.set(template.name, template) +} + +/** + * Return the names and titles of all registered templates. + */ +export const listTemplates = (): Array<{ name: string; title: string }> => + [...registry.values()].map((t) => ({ name: t.name, title: t.title })) + +/** + * Look up a template by name. + * + * @param name - The template name. + * @returns The template, or `undefined` if not found. + */ +// biome-ignore lint/suspicious/noExplicitAny: intentional — callers must narrow the returned template +export const getTemplate = (name: string): ReportTemplate | undefined => registry.get(name) + +// --------------------------------------------------------------------------- +// Built-in registrations +// --------------------------------------------------------------------------- + +registerTemplate(MonthlyReportTemplate) diff --git a/packages/skills/reports/src/templates/types.ts b/packages/skills/reports/src/templates/types.ts new file mode 100644 index 0000000..4dd1935 --- /dev/null +++ b/packages/skills/reports/src/templates/types.ts @@ -0,0 +1,64 @@ +/** + * Core types for the reports skill template system. + */ + +/** Supported output formats for report rendering. */ +export type ReportFormat = "pdf" | "pptx" | "xlsx" + +/** Options passed to a template renderer. */ +export interface RenderOpts { + /** Output format requested by the caller. */ + format: ReportFormat + /** Absolute path where the rendered file should be written. */ + outputPath: string +} + +/** + * A report template that can render structured data into one or more formats. + * + * @typeParam T - The validated data shape this template accepts. + */ +export interface ReportTemplate { + /** Unique machine-readable name used to look up the template. */ + name: string + /** Human-readable title shown in listings. */ + title: string + /** Formats this template supports. */ + formats: ReportFormat[] + /** + * Validate and parse raw input data into the typed shape T. + * Should throw a descriptive error on invalid input. + */ + parse: (raw: unknown) => T + /** + * Render the report data to the requested format and write the result to outputPath. + * Returns the absolute path of the written file. + */ + render: (data: T, opts: RenderOpts) => Promise +} + +/** One row of session-level metrics for a monthly report. */ +export interface SessionMetricRow { + /** Session identifier. */ + sessionId: string + /** Total number of messages in the session. */ + messageCount: number + /** Total tool calls made during the session. */ + toolCallCount: number + /** Session duration in seconds. */ + durationSeconds: number +} + +/** Aggregated data driving a monthly report. */ +export interface MonthlyReportData { + /** Report period label, e.g. "March 2026". */ + period: string + /** Total sessions started in the period. */ + totalSessions: number + /** Total messages exchanged in the period. */ + totalMessages: number + /** Total tool calls in the period. */ + totalToolCalls: number + /** Per-session breakdown. */ + sessions: SessionMetricRow[] +} diff --git a/packages/skills/reports/tsconfig.json b/packages/skills/reports/tsconfig.json index 7cb90b0..714f148 100644 --- a/packages/skills/reports/tsconfig.json +++ b/packages/skills/reports/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "dist", - "rootDir": "src" + "rootDir": "src", + "jsx": "react-jsx", + "jsxImportSource": "react" }, "include": ["src"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8272f05..bbd07db 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -672,10 +672,35 @@ importers: version: 5.9.3 packages/skills/reports: + dependencies: + '@react-pdf/renderer': + specifier: ^4.3.0 + version: 4.3.2(react@19.2.4) + '@sinclair/typebox': + specifier: ^0.34.9 + version: 0.34.48 + chart.js: + specifier: ^4.4.9 + version: 4.5.1 + chartjs-node-canvas: + specifier: ^4.1.6 + version: 4.1.6(chart.js@4.5.1) + exceljs: + specifier: ^4.4.0 + version: 4.4.0 + pptxgenjs: + specifier: ^3.12.0 + version: 3.12.0 + react: + specifier: ^19.1.0 + version: 19.2.4 devDependencies: '@types/node': specifier: ^22.15.2 version: 22.19.15 + '@types/react': + specifier: ^19.1.2 + version: 19.2.14 typescript: specifier: ^5.7.3 version: 5.9.3 @@ -1192,6 +1217,12 @@ packages: cpu: [x64] os: [win32] + '@fast-csv/format@4.3.5': + resolution: {integrity: sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==} + + '@fast-csv/parse@4.3.6': + resolution: {integrity: sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==} + '@floating-ui/core@1.7.5': resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} @@ -1420,6 +1451,13 @@ packages: '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + '@kurkle/color@0.3.4': + resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} + + '@mapbox/node-pre-gyp@1.0.11': + resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + hasBin: true + '@mariozechner/clipboard-darwin-arm64@0.3.2': resolution: {integrity: sha512-uBf6K7Je1ihsgvmWxA8UCGCeI+nbRVRXoarZdLjl6slz94Zs1tNKFZqx7aCI5O1i3e0B6ja82zZ06BWrl0MCVw==} engines: {node: '>= 10'} @@ -2421,6 +2459,49 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + '@react-pdf/fns@3.1.2': + resolution: {integrity: sha512-qTKGUf0iAMGg2+OsUcp9ffKnKi41RukM/zYIWMDJ4hRVYSr89Q7e3wSDW/Koqx3ea3Uy/z3h2y3wPX6Bdfxk6g==} + + '@react-pdf/font@4.0.4': + resolution: {integrity: sha512-8YtgGtL511txIEc9AjiilpZ7yjid8uCd8OGUl6jaL3LIHnrToUupSN4IzsMQpVTCMYiDLFnDNQzpZsOYtRS/Pg==} + + '@react-pdf/image@3.0.4': + resolution: {integrity: sha512-z0ogVQE0bKqgXQ5smgzIU857rLV7bMgVdrYsu3UfXDDLSzI7QPvzf6MFTFllX6Dx2rcsF13E01dqKPtJEM799g==} + + '@react-pdf/layout@4.4.2': + resolution: {integrity: sha512-gNu2oh8MiGR+NJZYTJ4c4q0nWCESBI6rKFiodVhE7OeVAjtzZzd6l65wsN7HXdWJqOZD3ttD97iE+tf5SOd/Yg==} + + '@react-pdf/pdfkit@4.1.0': + resolution: {integrity: sha512-Wm/IOAv0h/U5Ra94c/PltFJGcpTUd/fwVMVeFD6X9tTTPCttIwg0teRG1Lqq617J8K4W7jpL/B0HTH0mjp3QpQ==} + + '@react-pdf/png-js@3.0.0': + resolution: {integrity: sha512-eSJnEItZ37WPt6Qv5pncQDxLJRK15eaRwPT+gZoujP548CodenOVp49GST8XJvKMFt9YqIBzGBV/j9AgrOQzVA==} + + '@react-pdf/primitives@4.1.1': + resolution: {integrity: sha512-IuhxYls1luJb7NUWy6q5avb1XrNaVj9bTNI40U9qGRuS6n7Hje/8H8Qi99Z9UKFV74bBP3DOf3L1wV2qZVgVrQ==} + + '@react-pdf/reconciler@2.0.0': + resolution: {integrity: sha512-7zaPRujpbHSmCpIrZ+b9HSTJHthcVZzX0Wx7RzvQGsGBUbHP4p6s5itXrAIOuQuPvDepoHGNOvf6xUuMVvdoyw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@react-pdf/render@4.3.2': + resolution: {integrity: sha512-el5KYM1sH/PKcO4tRCIm8/AIEmhtraaONbwCrBhFdehoGv6JtgnXiMxHGAvZbI5kEg051GbyP+XIU6f6YbOu6Q==} + + '@react-pdf/renderer@4.3.2': + resolution: {integrity: sha512-EhPkj35gO9rXIyyx29W3j3axemvVY5RigMmlK4/6Ku0pXB8z9PEE/sz4ZBOShu2uot6V4xiCR3aG+t9IjJJlBQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@react-pdf/stylesheet@6.1.2': + resolution: {integrity: sha512-E3ftGRYUQGKiN3JOgtGsLDo0hGekA6dmkmi/MYACytmPTKxQRBSO3126MebmCq+t1rgU9uRlREIEawJ+8nzSbw==} + + '@react-pdf/textkit@6.1.0': + resolution: {integrity: sha512-sFlzDC9CDFrJsnL3B/+NHrk9+Advqk7iJZIStiYQDdskbow8GF/AGYrpIk+vWSnh35YxaGbHkqXq53XOxnyrjQ==} + + '@react-pdf/types@2.9.2': + resolution: {integrity: sha512-dufvpKId9OajLLbgn9q7VLUmyo1Jf+iyGk2ZHmCL8nIDtL8N1Ejh9TH7+pXXrR0tdie1nmnEb5Bz9U7g4hI4/g==} + '@remirror/core-constants@3.0.0': resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} @@ -3353,6 +3434,12 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@14.18.63': + resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==} + + '@types/node@18.19.130': + resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} + '@types/node@22.19.15': resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} @@ -3463,6 +3550,12 @@ packages: resolution: {integrity: sha512-JtCjTvbBVNP43mmuCqhSXk16XSKE5L4/4wbVFJsz6K2syfplNUnsZxHxnqJ0dQoe3Fy70V09uWI29uaXkNdjrg==} engines: {node: '>=16.0.0'} + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + + abs-svg-path@0.1.1: + resolution: {integrity: sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==} + accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} @@ -3472,6 +3565,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -3508,6 +3605,26 @@ packages: any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + aproba@2.1.0: + resolution: {integrity: sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==} + + archiver-utils@2.1.0: + resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} + engines: {node: '>= 6'} + + archiver-utils@3.0.4: + resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==} + engines: {node: '>= 10'} + + archiver@5.3.2: + resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} + engines: {node: '>= 10'} + + are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -3532,6 +3649,9 @@ packages: async@3.2.3: resolution: {integrity: sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==} + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -3555,6 +3675,10 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} + base64-js@0.0.8: + resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==} + engines: {node: '>= 0.4'} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -3640,9 +3764,25 @@ packages: zod: optional: true + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + + big-integer@1.6.52: + resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} + engines: {node: '>=0.6'} + bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + binary@0.3.0: + resolution: {integrity: sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + bluebird@3.4.7: + resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==} + bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} @@ -3653,10 +3793,22 @@ packages: bowser@2.14.1: resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + brace-expansion@1.1.13: + resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} + + brace-expansion@2.0.3: + resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==} + brace-expansion@5.0.4: resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} engines: {node: 18 || 20 || >=22} + brotli@1.3.3: + resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} + + browserify-zlib@0.2.0: + resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} + bson@7.2.0: resolution: {integrity: sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ==} engines: {node: '>=20.19.0'} @@ -3667,6 +3819,17 @@ packages: buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + buffer-indexof-polyfill@1.0.2: + resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==} + engines: {node: '>=0.10'} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffers@0.1.1: + resolution: {integrity: sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==} + engines: {node: '>=0.2.0'} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -3690,6 +3853,10 @@ packages: caniuse-lite@1.0.30001780: resolution: {integrity: sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==} + canvas@2.11.2: + resolution: {integrity: sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==} + engines: {node: '>=6'} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -3697,6 +3864,9 @@ packages: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} + chainsaw@0.1.0: + resolution: {integrity: sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -3717,6 +3887,15 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + chart.js@4.5.1: + resolution: {integrity: sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==} + engines: {pnpm: '>=8'} + + chartjs-node-canvas@4.1.6: + resolution: {integrity: sha512-UQJbPWrvqB/FoLclGA9BaLQmZbzSYlujF4w8NZd6Xzb+sqgACBb2owDX6m7ifCXLjUW5Nz0Qx0qqrTtQkkSoYw==} + peerDependencies: + chart.js: ^3.5.1 + check-error@2.1.3: resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} @@ -3729,6 +3908,10 @@ packages: chevrotain@11.1.2: resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==} + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -3753,6 +3936,10 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -3770,6 +3957,13 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + colors@1.0.3: resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} engines: {node: '>=0.1.90'} @@ -3793,9 +3987,19 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + compress-commons@4.1.2: + resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} + engines: {node: '>= 10'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + content-disposition@1.0.1: resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} engines: {node: '>=18'} @@ -3812,6 +4016,9 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cors@2.8.6: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} @@ -3826,6 +4033,15 @@ packages: resolution: {integrity: sha512-/2yieBqvMcRj8McNzkycjW2v3OIUOibBfd2dLEJ0nWts8NobAxwiyw9phVNS6oDL8x8tz9F7uNVFEVpJncQpeA==} engines: {node: '>=8.0.0'} + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@4.0.3: + resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} + engines: {node: '>= 10'} + crelt@1.0.6: resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} @@ -3833,6 +4049,9 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} @@ -4054,6 +4273,10 @@ packages: decode-named-character-reference@1.3.0: resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + decompress-response@4.2.1: + resolution: {integrity: sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==} + engines: {node: '>=8'} + deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} @@ -4076,6 +4299,9 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + denque@2.1.0: resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} engines: {node: '>=0.10'} @@ -4098,6 +4324,9 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dfa@1.2.0: + resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==} + diff@8.0.3: resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} engines: {node: '>=0.3.1'} @@ -4120,6 +4349,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} @@ -4139,6 +4371,9 @@ packages: embla-carousel@8.6.0: resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4239,6 +4474,10 @@ packages: eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + eventsource-parser@3.0.6: resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} engines: {node: '>=18.0.0'} @@ -4247,6 +4486,10 @@ packages: resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} engines: {node: '>=18.0.0'} + exceljs@4.4.0: + resolution: {integrity: sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg==} + engines: {node: '>=8.3.0'} + execa@9.6.1: resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} engines: {node: ^18.19.0 || >=20.5.0} @@ -4271,6 +4514,10 @@ packages: resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} engines: {node: '> 0.1.90'} + fast-csv@4.3.6: + resolution: {integrity: sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==} + engines: {node: '>=10.0.0'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -4332,6 +4579,9 @@ packages: debug: optional: true + fontkit@2.0.4: + resolution: {integrity: sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==} + form-data@4.0.5: resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} @@ -4362,14 +4612,34 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + fstream@1.0.12: + resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==} + engines: {node: '>=0.6'} + deprecated: This package is no longer supported. + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + gaxios@7.1.4: resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} engines: {node: '>=18'} @@ -4420,6 +4690,10 @@ packages: resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} engines: {node: 18 || 20 || >=22} + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + google-auth-library@10.6.2: resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} engines: {node: '>=18'} @@ -4450,6 +4724,9 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -4511,6 +4788,12 @@ packages: resolution: {integrity: sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==} engines: {node: ^20.17.0 || >=22.9.0} + hsl-to-hex@1.0.0: + resolution: {integrity: sha512-K6GVpucS5wFf44X0h2bLVRDsycgJmf9FF2elg+CrqD8GcFU8c6vYhgXn8NjUkFCwj+xDFb70qgLbTUm6sxwPmA==} + + hsl-to-rgb-for-reals@1.1.1: + resolution: {integrity: sha512-LgOWAkrN0rFaQpfdWBQlv/VhkOxb5AsBjk6NQVx4yEzWS923T07X0M1Y0VNko2H52HeSpZrZNNMJ0aFqsdVzQg==} + html-url-attributes@3.0.1: resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} @@ -4525,14 +4808,24 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + https@1.0.0: + resolution: {integrity: sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==} + human-signals@8.0.1: resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} engines: {node: '>=18.18.0'} + hyphen@1.14.1: + resolution: {integrity: sha512-kvL8xYl5QMTh+LwohVN72ciOxC0OEV79IPdJSTwEXok9y9QHebXGdFgrED4sWfiax/ODx++CAMk3hMy4XPJPOw==} + iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -4548,10 +4841,22 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} + image-size@1.2.1: + resolution: {integrity: sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==} + engines: {node: '>=16.x'} + hasBin: true + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + inflection@1.13.4: resolution: {integrity: sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==} engines: {'0': node >= 0.4.0} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -4582,6 +4887,9 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + is-core-module@2.16.1: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} @@ -4621,12 +4929,21 @@ packages: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + jay-peg@1.1.1: + resolution: {integrity: sha512-D62KEuBxz/ip2gQKOEhk/mx14o7eiFRaU+VNNSP4MOiIkwb/D6B3G1Mfas7C/Fit8EsSV2/IWjZElx/Gs6A4ww==} + jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -4660,6 +4977,9 @@ packages: resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} engines: {node: '>=12', npm: '>=6'} + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + jwa@2.0.1: resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} @@ -4694,6 +5014,13 @@ packages: layout-base@2.0.1: resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -4768,12 +5095,18 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} + linebreak@1.1.0: + resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} + linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} linkifyjs@4.3.2: resolution: {integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==} + listenercount@1.0.1: + resolution: {integrity: sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -4787,15 +5120,37 @@ packages: lodash.defaults@4.2.0: resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + lodash.difference@4.5.0: + resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + + lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + + lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + + lodash.groupby@4.6.0: + resolution: {integrity: sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==} + lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} lodash.isboolean@3.0.3: resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + + lodash.isfunction@3.0.9: + resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} + lodash.isinteger@4.0.4: resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + lodash.isnil@4.0.0: + resolution: {integrity: sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==} + lodash.isnumber@3.0.3: resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} @@ -4805,9 +5160,18 @@ packages: lodash.isstring@4.0.1: resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + lodash.isundefined@3.0.1: + resolution: {integrity: sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==} + lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + lodash.union@4.6.0: + resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + lodash@4.17.23: resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} @@ -4849,6 +5213,10 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + markdown-it@14.1.1: resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} hasBin: true @@ -4926,6 +5294,9 @@ packages: mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + media-engine@1.0.3: + resolution: {integrity: sha512-aa5tG6sDoK+k70B9iEX1NeyfT8ObCKhNDs6lJVpwF6r8vhUfuKMslIcirq6HIUYuuUYLefcEQOn9bSBOvawtwg==} + media-typer@1.1.0: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} @@ -5072,21 +5443,49 @@ packages: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} + mimic-response@2.1.0: + resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==} + engines: {node: '>=8'} + minimatch@10.2.4: resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} engines: {node: 18 || 20 || >=22} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + mlly@1.8.1: resolution: {integrity: sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==} @@ -5224,6 +5623,15 @@ packages: engines: {node: '>=10.5.0'} deprecated: Use your platform's native DOMException instead + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-fetch@3.3.2: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -5233,10 +5641,26 @@ packages: engines: {node: '>=0.1.97'} os: [linux, darwin, freebsd, win32, smartos, sunos] + nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-svg-path@1.1.0: + resolution: {integrity: sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==} + npm-run-path@6.0.0: resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} engines: {node: '>=18'} + npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -5312,6 +5736,12 @@ packages: package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + parse-database-url@0.3.0: resolution: {integrity: sha512-YRxDoVBAUk3ksGF9pud+aqWwXmThZzhX9Z1PPxKU03BB3/gu2RcgyMA4rktMYhkIJ9KxwW7lIj00U+TSNz80wg==} engines: {node: '>= 0.6'} @@ -5323,6 +5753,9 @@ packages: resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} engines: {node: '>=18'} + parse-svg-path@0.1.2: + resolution: {integrity: sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==} + parse5-htmlparser2-tree-adapter@6.0.1: resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} @@ -5353,6 +5786,10 @@ packages: resolution: {integrity: sha512-qdVgY8KXmVdJZRSS1JdEPOKPdTiEK/pi0RkcT2sw1RhXxohdujUlJFPuS1TSkevZ9vzd3ZlL7ULl1MHGTApKzQ==} engines: {node: '>=14.0.0'} + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -5431,6 +5868,9 @@ packages: points-on-path@0.2.1: resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + postcss@8.4.31: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} @@ -5455,10 +5895,16 @@ packages: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} + pptxgenjs@3.12.0: + resolution: {integrity: sha512-ZozkYKWb1MoPR4ucw3/aFYlHkVIJxo9czikEclcUVnS4Iw/M+r+TEwdlB3fyAWO9JY1USxJDt0Y0/r15IR/RUA==} + pretty-ms@9.3.0: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + prompt@1.3.0: resolution: {integrity: sha512-ZkaRWtaLBZl7KKAKndKYUL8WqNT+cQHKRZnT4RYYms48jQkFw3rrBL+/N5K/KtdEveHkxs982MX2BkDKub2ZMg==} engines: {node: '>= 6.0.0'} @@ -5560,6 +6006,9 @@ packages: resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} engines: {node: '>=0.6'} + queue@6.0.2: + resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} + radix-ui@1.4.3: resolution: {integrity: sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==} peerDependencies: @@ -5664,6 +6113,16 @@ packages: resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} engines: {node: '>=0.8'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + recharts-scale@0.4.5: resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} @@ -5752,6 +6211,9 @@ packages: engines: {node: '>= 0.4'} hasBin: true + restructure@3.0.2: + resolution: {integrity: sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==} + retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -5764,6 +6226,16 @@ packages: resolution: {integrity: sha512-xcBILK2pA9oh4SiinPEZfhP8HfrB/ha+a2fTMyl7Om2WjlDVrOQy99N2MXXlUHqGJz4qEu2duXxHJjDWuK/0xg==} engines: {node: '>= 0.4.0'} + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} @@ -5788,12 +6260,22 @@ packages: rw@1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + saxes@5.0.1: + resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} + engines: {node: '>=10'} + + scheduler@0.25.0-rc-603e6108-20241029: + resolution: {integrity: sha512-pFwF6H1XrSdYYNLfOcGlM28/j8CGLu8IvdrxqhjWULe2bPcKiKW4CV+OWqR/9fT52mywx65l7ysNkjLKBda7eA==} + scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} @@ -5801,6 +6283,10 @@ packages: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + semver@7.7.4: resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} @@ -5820,6 +6306,9 @@ packages: set-cookie-parser@3.0.1: resolution: {integrity: sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==} + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -5864,6 +6353,15 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@3.1.1: + resolution: {integrity: sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==} + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -5933,6 +6431,12 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} @@ -5992,6 +6496,9 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svg-arc-to-cubic-bezier@3.2.0: + resolution: {integrity: sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g==} + tailwind-merge@3.5.0: resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} @@ -6002,6 +6509,15 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -6009,6 +6525,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -6038,6 +6557,10 @@ packages: resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} engines: {node: '>=14.0.0'} + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -6049,10 +6572,16 @@ packages: tokenlens@1.3.1: resolution: {integrity: sha512-7oxmsS5PNCX3z+b+z07hL5vCzlgHKkCGrEQjQmWl5l+v5cUrtL7S1cuST4XThaL1XyjbTX8J5hfP0cjDJRkaLA==} + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@5.1.1: resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} engines: {node: '>=18'} + traverse@0.3.9: + resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==} + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -6120,6 +6649,9 @@ packages: resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} engines: {node: '>=18'} + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -6127,6 +6659,12 @@ packages: resolution: {integrity: sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==} engines: {node: '>=20.18.1'} + unicode-properties@1.4.1: + resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} + + unicode-trie@2.0.0: + resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} + unicorn-magic@0.3.0: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} @@ -6159,6 +6697,9 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unzipper@0.10.14: + resolution: {integrity: sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==} + use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -6195,6 +6736,9 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + uuid@11.1.0: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true @@ -6203,6 +6747,10 @@ packages: resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} hasBin: true + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -6225,6 +6773,10 @@ packages: victory-vendor@36.9.2: resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + vite-compatible-readable-stream@3.6.1: + resolution: {integrity: sha512-t20zYkrSf868+j/p31cRIGN28Phrjm3nRSLR2fyc2tiWi4cZGVdv68yNlwnIINTkMTmPoMiSlc0OadaO7DXZaQ==} + engines: {node: '>= 6'} + vite-node@3.2.4: resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -6328,6 +6880,9 @@ packages: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} @@ -6336,6 +6891,9 @@ packages: resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} engines: {node: '>=18'} + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + when@2.0.1: resolution: {integrity: sha512-h0l57vFJ4YQe1/U+C+oqBfAoopxXABUm6VqWM0x2gg4pARru4IUWo/PAxyawWgbGtndXrZbA41EzsfxacZVEXQ==} @@ -6352,6 +6910,9 @@ packages: engines: {node: '>=8'} hasBin: true + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + winston@2.4.7: resolution: {integrity: sha512-vLB4BqzCKDnnZH9PHGoS2ycawueX4HLqENXQitvFHczhgW2vFpSOn31LZtVr1KU8YTw7DS4tM+cqyovxo8taVg==} engines: {node: '>= 0.10.0'} @@ -6379,6 +6940,9 @@ packages: utf-8-validate: optional: true + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -6390,6 +6954,9 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yaml@2.8.2: resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} @@ -6426,6 +6993,13 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} + yoga-layout@3.2.1: + resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} + + zip-stream@4.1.1: + resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} + engines: {node: '>= 10'} + zod-to-json-schema@3.25.1: resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} peerDependencies: @@ -6912,14 +7486,14 @@ snapshots: nanostores: 1.2.0 zod: 4.3.6 - '@better-auth/drizzle-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/drizzle-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/kysely-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13)': + '@better-auth/kysely-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 kysely: 0.28.13 @@ -6929,25 +7503,25 @@ snapshots: '@better-auth/utils': 0.3.1 kysely: 0.28.14 - '@better-auth/memory-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/memory-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/mongo-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7))': + '@better-auth/mongo-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7))': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 mongodb: 7.1.0(socks@2.8.7) - '@better-auth/prisma-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/prisma-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/telemetry@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))': + '@better-auth/telemetry@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 @@ -7123,6 +7697,25 @@ snapshots: '@esbuild/win32-x64@0.27.4': optional: true + '@fast-csv/format@4.3.5': + dependencies: + '@types/node': 14.18.63 + lodash.escaperegexp: 4.1.2 + lodash.isboolean: 3.0.3 + lodash.isequal: 4.5.0 + lodash.isfunction: 3.0.9 + lodash.isnil: 4.0.0 + + '@fast-csv/parse@4.3.6': + dependencies: + '@types/node': 14.18.63 + lodash.escaperegexp: 4.1.2 + lodash.groupby: 4.6.0 + lodash.isfunction: 3.0.9 + lodash.isnil: 4.0.0 + lodash.isundefined: 3.0.1 + lodash.uniq: 4.5.0 + '@floating-ui/core@1.7.5': dependencies: '@floating-ui/utils': 0.2.11 @@ -7302,6 +7895,23 @@ snapshots: '@js-sdsl/ordered-map@4.4.2': {} + '@kurkle/color@0.3.4': {} + + '@mapbox/node-pre-gyp@1.0.11': + dependencies: + detect-libc: 2.1.2 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.7.4 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + '@mariozechner/clipboard-darwin-arm64@0.3.2': optional: true @@ -8345,18 +8955,119 @@ snapshots: '@radix-ui/rect@1.1.1': {} - '@remirror/core-constants@3.0.0': {} + '@react-pdf/fns@3.1.2': {} - '@rollup/rollup-android-arm-eabi@4.60.0': - optional: true + '@react-pdf/font@4.0.4': + dependencies: + '@react-pdf/pdfkit': 4.1.0 + '@react-pdf/types': 2.9.2 + fontkit: 2.0.4 + is-url: 1.2.4 - '@rollup/rollup-android-arm64@4.60.0': - optional: true + '@react-pdf/image@3.0.4': + dependencies: + '@react-pdf/png-js': 3.0.0 + jay-peg: 1.1.1 - '@rollup/rollup-darwin-arm64@4.60.0': - optional: true + '@react-pdf/layout@4.4.2': + dependencies: + '@react-pdf/fns': 3.1.2 + '@react-pdf/image': 3.0.4 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/stylesheet': 6.1.2 + '@react-pdf/textkit': 6.1.0 + '@react-pdf/types': 2.9.2 + emoji-regex-xs: 1.0.0 + queue: 6.0.2 + yoga-layout: 3.2.1 - '@rollup/rollup-darwin-x64@4.60.0': + '@react-pdf/pdfkit@4.1.0': + dependencies: + '@babel/runtime': 7.29.2 + '@react-pdf/png-js': 3.0.0 + browserify-zlib: 0.2.0 + crypto-js: 4.2.0 + fontkit: 2.0.4 + jay-peg: 1.1.1 + linebreak: 1.1.0 + vite-compatible-readable-stream: 3.6.1 + + '@react-pdf/png-js@3.0.0': + dependencies: + browserify-zlib: 0.2.0 + + '@react-pdf/primitives@4.1.1': {} + + '@react-pdf/reconciler@2.0.0(react@19.2.4)': + dependencies: + object-assign: 4.1.1 + react: 19.2.4 + scheduler: 0.25.0-rc-603e6108-20241029 + + '@react-pdf/render@4.3.2': + dependencies: + '@babel/runtime': 7.29.2 + '@react-pdf/fns': 3.1.2 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/textkit': 6.1.0 + '@react-pdf/types': 2.9.2 + abs-svg-path: 0.1.1 + color-string: 1.9.1 + normalize-svg-path: 1.1.0 + parse-svg-path: 0.1.2 + svg-arc-to-cubic-bezier: 3.2.0 + + '@react-pdf/renderer@4.3.2(react@19.2.4)': + dependencies: + '@babel/runtime': 7.29.2 + '@react-pdf/fns': 3.1.2 + '@react-pdf/font': 4.0.4 + '@react-pdf/layout': 4.4.2 + '@react-pdf/pdfkit': 4.1.0 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/reconciler': 2.0.0(react@19.2.4) + '@react-pdf/render': 4.3.2 + '@react-pdf/types': 2.9.2 + events: 3.3.0 + object-assign: 4.1.1 + prop-types: 15.8.1 + queue: 6.0.2 + react: 19.2.4 + + '@react-pdf/stylesheet@6.1.2': + dependencies: + '@react-pdf/fns': 3.1.2 + '@react-pdf/types': 2.9.2 + color-string: 1.9.1 + hsl-to-hex: 1.0.0 + media-engine: 1.0.3 + postcss-value-parser: 4.2.0 + + '@react-pdf/textkit@6.1.0': + dependencies: + '@react-pdf/fns': 3.1.2 + bidi-js: 1.0.3 + hyphen: 1.14.1 + unicode-properties: 1.4.1 + + '@react-pdf/types@2.9.2': + dependencies: + '@react-pdf/font': 4.0.4 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/stylesheet': 6.1.2 + + '@remirror/core-constants@3.0.0': {} + + '@rollup/rollup-android-arm-eabi@4.60.0': + optional: true + + '@rollup/rollup-android-arm64@4.60.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.0': + optional: true + + '@rollup/rollup-darwin-x64@4.60.0': optional: true '@rollup/rollup-freebsd-arm64@4.60.0': @@ -9387,6 +10098,12 @@ snapshots: '@types/ms@2.1.0': {} + '@types/node@14.18.63': {} + + '@types/node@18.19.130': + dependencies: + undici-types: 5.26.5 + '@types/node@22.19.15': dependencies: undici-types: 6.21.0 @@ -9537,6 +10254,10 @@ snapshots: - debug - supports-color + abbrev@1.1.1: {} + + abs-svg-path@0.1.1: {} + accepts@2.0.0: dependencies: mime-types: 3.0.2 @@ -9544,6 +10265,12 @@ snapshots: acorn@8.16.0: {} + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + agent-base@7.1.4: {} ai@6.0.116(zod@4.3.6): @@ -9575,6 +10302,49 @@ snapshots: any-promise@1.3.0: {} + aproba@2.1.0: {} + + archiver-utils@2.1.0: + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 2.3.8 + + archiver-utils@3.0.4: + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + + archiver@5.3.2: + dependencies: + archiver-utils: 2.1.0 + async: 3.2.6 + buffer-crc32: 0.2.13 + readable-stream: 3.6.2 + readdir-glob: 1.1.3 + tar-stream: 2.2.0 + zip-stream: 4.1.1 + + are-we-there-yet@2.0.0: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + argparse@2.0.1: {} aria-hidden@1.2.6: @@ -9597,6 +10367,8 @@ snapshots: async@3.2.3: {} + async@3.2.6: {} + asynckit@0.4.0: {} aws-ssl-profiles@1.1.2: {} @@ -9619,6 +10391,8 @@ snapshots: balanced-match@4.0.4: {} + base64-js@0.0.8: {} + base64-js@1.5.1: {} baseline-browser-mapping@2.10.8: {} @@ -9632,12 +10406,12 @@ snapshots: better-auth@1.5.5(mongodb@7.1.0(socks@2.8.7))(mysql2@3.20.0(@types/node@22.19.15))(next@16.2.0(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) - '@better-auth/drizzle-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/kysely-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13) - '@better-auth/memory-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/mongo-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7)) - '@better-auth/prisma-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/telemetry': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0)) + '@better-auth/drizzle-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1) + '@better-auth/kysely-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13) + '@better-auth/memory-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1) + '@better-auth/mongo-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7)) + '@better-auth/prisma-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1) + '@better-auth/telemetry': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0)) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 '@noble/ciphers': 2.1.1 @@ -9668,8 +10442,27 @@ snapshots: optionalDependencies: zod: 4.3.6 + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + + big-integer@1.6.52: {} + bignumber.js@9.3.1: {} + binary@0.3.0: + dependencies: + buffers: 0.1.1 + chainsaw: 0.1.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + bluebird@3.4.7: {} + bluebird@3.7.2: {} body-parser@2.2.2: @@ -9688,16 +10481,42 @@ snapshots: bowser@2.14.1: {} + brace-expansion@1.1.13: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.3: + dependencies: + balanced-match: 1.0.2 + brace-expansion@5.0.4: dependencies: balanced-match: 4.0.4 + brotli@1.3.3: + dependencies: + base64-js: 1.5.1 + + browserify-zlib@0.2.0: + dependencies: + pako: 1.0.11 + bson@7.2.0: {} buffer-crc32@0.2.13: {} buffer-equal-constant-time@1.0.1: {} + buffer-indexof-polyfill@1.0.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffers@0.1.1: {} + bytes@3.1.2: {} cac@6.7.14: {} @@ -9716,6 +10535,15 @@ snapshots: caniuse-lite@1.0.30001780: {} + canvas@2.11.2: + dependencies: + '@mapbox/node-pre-gyp': 1.0.11 + nan: 2.26.2 + simple-get: 3.1.1 + transitivePeerDependencies: + - encoding + - supports-color + ccount@2.0.1: {} chai@5.3.3: @@ -9726,6 +10554,10 @@ snapshots: loupe: 3.2.1 pathval: 2.0.1 + chainsaw@0.1.0: + dependencies: + traverse: 0.3.9 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -9741,6 +10573,19 @@ snapshots: character-reference-invalid@2.0.1: {} + chart.js@4.5.1: + dependencies: + '@kurkle/color': 0.3.4 + + chartjs-node-canvas@4.1.6(chart.js@4.5.1): + dependencies: + canvas: 2.11.2 + chart.js: 4.5.1 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + - supports-color + check-error@2.1.3: {} chevrotain-allstar@0.3.1(chevrotain@11.1.2): @@ -9757,6 +10602,8 @@ snapshots: '@chevrotain/utils': 11.1.2 lodash-es: 4.17.23 + chownr@2.0.0: {} + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -9792,6 +10639,8 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clone@2.1.2: {} + clsx@2.1.1: {} cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): @@ -9812,6 +10661,13 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + + color-support@1.1.3: {} + colors@1.0.3: {} combined-stream@1.0.8: @@ -9826,8 +10682,19 @@ snapshots: commander@8.3.0: {} + compress-commons@4.1.2: + dependencies: + buffer-crc32: 0.2.13 + crc32-stream: 4.0.3 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + + concat-map@0.0.1: {} + confbox@0.1.8: {} + console-control-strings@1.1.0: {} + content-disposition@1.0.1: {} content-type@1.0.5: {} @@ -9836,6 +10703,8 @@ snapshots: cookie@0.7.2: {} + core-util-is@1.0.3: {} + cors@2.8.6: dependencies: object-assign: 4.1.1 @@ -9854,6 +10723,13 @@ snapshots: nan: 2.26.2 optional: true + crc-32@1.2.2: {} + + crc32-stream@4.0.3: + dependencies: + crc-32: 1.2.2 + readable-stream: 3.6.2 + crelt@1.0.6: {} cross-spawn@7.0.6: @@ -9862,6 +10738,8 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crypto-js@4.2.0: {} + csstype@3.2.3: {} cycle@1.0.3: {} @@ -10111,6 +10989,10 @@ snapshots: dependencies: character-entities: 2.0.2 + decompress-response@4.2.1: + dependencies: + mimic-response: 2.1.0 + deep-eql@5.0.2: {} deep-extend@0.6.0: {} @@ -10129,6 +11011,8 @@ snapshots: delayed-stream@1.0.0: {} + delegates@1.0.0: {} + denque@2.1.0: {} depd@2.0.0: {} @@ -10143,6 +11027,8 @@ snapshots: dependencies: dequal: 2.0.3 + dfa@1.2.0: {} + diff@8.0.3: {} dom-helpers@5.2.1: @@ -10164,6 +11050,10 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + duplexer2@0.1.4: + dependencies: + readable-stream: 2.3.8 + ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer: 5.2.1 @@ -10182,6 +11072,8 @@ snapshots: embla-carousel@8.6.0: {} + emoji-regex-xs@1.0.0: {} + emoji-regex@8.0.0: {} encodeurl@2.0.0: {} @@ -10285,12 +11177,26 @@ snapshots: eventemitter3@5.0.4: {} + events@3.3.0: {} + eventsource-parser@3.0.6: {} eventsource@3.0.7: dependencies: eventsource-parser: 3.0.6 + exceljs@4.4.0: + dependencies: + archiver: 5.3.2 + dayjs: 1.11.20 + fast-csv: 4.3.6 + jszip: 3.10.1 + readable-stream: 3.6.2 + saxes: 5.0.1 + tmp: 0.2.5 + unzipper: 0.10.14 + uuid: 8.3.2 + execa@9.6.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 @@ -10355,6 +11261,11 @@ snapshots: eyes@0.1.8: {} + fast-csv@4.3.6: + dependencies: + '@fast-csv/format': 4.3.5 + '@fast-csv/parse': 4.3.6 + fast-deep-equal@3.1.3: {} fast-equals@5.4.0: {} @@ -10420,6 +11331,18 @@ snapshots: follow-redirects@1.15.11: {} + fontkit@2.0.4: + dependencies: + '@swc/helpers': 0.5.15 + brotli: 1.3.3 + clone: 2.1.2 + dfa: 1.2.0 + fast-deep-equal: 3.1.3 + restructure: 3.0.2 + tiny-inflate: 1.0.3 + unicode-properties: 1.4.1 + unicode-trie: 2.0.0 + form-data@4.0.5: dependencies: asynckit: 0.4.0 @@ -10445,11 +11368,38 @@ snapshots: fresh@2.0.0: {} + fs-constants@1.0.0: {} + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true + fstream@1.0.12: + dependencies: + graceful-fs: 4.2.11 + inherits: 2.0.4 + mkdirp: 0.5.6 + rimraf: 2.7.1 + function-bind@1.1.2: {} + gauge@3.0.2: + dependencies: + aproba: 2.1.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + gaxios@7.1.4: dependencies: extend: 3.0.2 @@ -10521,6 +11471,15 @@ snapshots: minipass: 7.1.3 path-scurry: 2.0.2 + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + google-auth-library@10.6.2: dependencies: base64-js: 1.5.1 @@ -10548,6 +11507,8 @@ snapshots: dependencies: has-symbols: 1.1.0 + has-unicode@2.0.1: {} + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -10688,6 +11649,12 @@ snapshots: dependencies: lru-cache: 11.2.7 + hsl-to-hex@1.0.0: + dependencies: + hsl-to-rgb-for-reals: 1.1.1 + + hsl-to-rgb-for-reals@1.1.1: {} + html-url-attributes@3.0.1: {} html-void-elements@3.0.0: {} @@ -10707,6 +11674,13 @@ snapshots: transitivePeerDependencies: - supports-color + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 @@ -10714,8 +11688,12 @@ snapshots: transitivePeerDependencies: - supports-color + https@1.0.0: {} + human-signals@8.0.1: {} + hyphen@1.14.1: {} + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -10728,8 +11706,19 @@ snapshots: ignore@7.0.5: {} + image-size@1.2.1: + dependencies: + queue: 6.0.2 + + immediate@3.0.6: {} + inflection@1.13.4: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + inherits@2.0.4: {} ini@1.3.8: {} @@ -10751,6 +11740,8 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 + is-arrayish@0.3.4: {} + is-core-module@2.16.1: dependencies: hasown: 2.0.2 @@ -10775,10 +11766,18 @@ snapshots: is-unicode-supported@2.1.0: {} + is-url@1.2.4: {} + + isarray@1.0.0: {} + isexe@2.0.0: {} isstream@0.1.2: {} + jay-peg@1.1.1: + dependencies: + restructure: 3.0.2 + jiti@2.6.1: {} jose@6.2.2: {} @@ -10815,6 +11814,13 @@ snapshots: ms: 2.1.3 semver: 7.7.4 + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + jwa@2.0.1: dependencies: buffer-equal-constant-time: 1.0.1 @@ -10851,6 +11857,14 @@ snapshots: layout-base@2.0.1: {} + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + + lie@3.3.0: + dependencies: + immediate: 3.0.6 + lightningcss-android-arm64@1.32.0: optional: true @@ -10900,12 +11914,19 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 + linebreak@1.1.0: + dependencies: + base64-js: 0.0.8 + unicode-trie: 2.0.0 + linkify-it@5.0.0: dependencies: uc.micro: 2.1.0 linkifyjs@4.3.2: {} + listenercount@1.0.1: {} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -10916,20 +11937,40 @@ snapshots: lodash.defaults@4.2.0: {} + lodash.difference@4.5.0: {} + + lodash.escaperegexp@4.1.2: {} + + lodash.flatten@4.4.0: {} + + lodash.groupby@4.6.0: {} + lodash.includes@4.3.0: {} lodash.isboolean@3.0.3: {} + lodash.isequal@4.5.0: {} + + lodash.isfunction@3.0.9: {} + lodash.isinteger@4.0.4: {} + lodash.isnil@4.0.0: {} + lodash.isnumber@3.0.3: {} lodash.isplainobject@4.0.6: {} lodash.isstring@4.0.1: {} + lodash.isundefined@3.0.1: {} + lodash.once@4.1.1: {} + lodash.union@4.6.0: {} + + lodash.uniq@4.5.0: {} + lodash@4.17.23: {} long@5.3.2: {} @@ -10960,6 +12001,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + markdown-it@14.1.1: dependencies: argparse: 2.0.1 @@ -11146,6 +12191,8 @@ snapshots: mdurl@2.0.0: {} + media-engine@1.0.3: {} + media-typer@1.1.0: {} memory-pager@1.5.0: {} @@ -11421,18 +12468,41 @@ snapshots: dependencies: mime-db: 1.54.0 + mimic-response@2.1.0: {} + minimatch@10.2.4: dependencies: brace-expansion: 5.0.4 + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.13 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.0.3 + minimist@1.2.8: {} + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + minipass@7.1.3: {} + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + mkdirp@0.5.6: dependencies: minimist: 1.2.8 + mkdirp@1.0.4: {} + mlly@1.8.1: dependencies: acorn: 8.16.0 @@ -11497,8 +12567,7 @@ snapshots: dependencies: lru.min: 1.1.4 - nan@2.26.2: - optional: true + nan@2.26.2: {} nanoid@3.3.11: {} @@ -11543,6 +12612,10 @@ snapshots: node-domexception@1.0.0: {} + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + node-fetch@3.3.2: dependencies: data-uri-to-buffer: 4.0.1 @@ -11551,11 +12624,28 @@ snapshots: node-fs@0.1.7: {} + nopt@5.0.0: + dependencies: + abbrev: 1.1.1 + + normalize-path@3.0.0: {} + + normalize-svg-path@1.1.0: + dependencies: + svg-arc-to-cubic-bezier: 3.2.0 + npm-run-path@6.0.0: dependencies: path-key: 4.0.0 unicorn-magic: 0.3.0 + npmlog@5.0.1: + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -11629,6 +12719,10 @@ snapshots: package-manager-detector@1.6.0: {} + pako@0.2.9: {} + + pako@1.0.11: {} + parse-database-url@0.3.0: dependencies: mongodb-uri: 0.9.7 @@ -11645,6 +12739,8 @@ snapshots: parse-ms@4.0.0: {} + parse-svg-path@0.1.2: {} + parse5-htmlparser2-tree-adapter@6.0.1: dependencies: parse5: 6.0.1 @@ -11667,6 +12763,8 @@ snapshots: path-expression-matcher@1.1.3: {} + path-is-absolute@1.0.1: {} + path-key@3.1.1: {} path-key@4.0.0: {} @@ -11738,6 +12836,8 @@ snapshots: path-data-parser: 0.1.0 points-on-curve: 0.2.0 + postcss-value-parser@4.2.0: {} + postcss@8.4.31: dependencies: nanoid: 3.3.11 @@ -11760,10 +12860,19 @@ snapshots: dependencies: xtend: 4.0.2 + pptxgenjs@3.12.0: + dependencies: + '@types/node': 18.19.130 + https: 1.0.0 + image-size: 1.2.1 + jszip: 3.10.1 + pretty-ms@9.3.0: dependencies: parse-ms: 4.0.0 + process-nextick-args@2.0.1: {} + prompt@1.3.0: dependencies: '@colors/colors': 1.5.0 @@ -11937,6 +13046,10 @@ snapshots: dependencies: side-channel: 1.1.0 + queue@6.0.2: + dependencies: + inherits: 2.0.4 + radix-ui@1.4.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@radix-ui/primitive': 1.1.3 @@ -12092,6 +13205,26 @@ snapshots: dependencies: mute-stream: 0.0.8 + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.9 + recharts-scale@0.4.5: dependencies: decimal.js-light: 2.5.1 @@ -12223,12 +13356,22 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + restructure@3.0.2: {} + retry@0.12.0: {} retry@0.13.1: {} revalidator@0.1.8: {} + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + robust-predicates@3.0.2: {} rollup@4.60.0: @@ -12285,14 +13428,24 @@ snapshots: rw@1.3.3: {} + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safer-buffer@2.1.2: {} + saxes@5.0.1: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.25.0-rc-603e6108-20241029: {} + scheduler@0.27.0: {} semver@5.7.2: {} + semver@6.3.1: {} + semver@7.7.4: {} send@1.2.1: @@ -12324,6 +13477,8 @@ snapshots: set-cookie-parser@3.0.1: {} + setimmediate@1.0.5: {} + setprototypeof@1.2.0: {} sharp@0.34.5: @@ -12409,6 +13564,18 @@ snapshots: signal-exit@4.1.0: {} + simple-concat@1.0.1: {} + + simple-get@3.1.1: + dependencies: + decompress-response: 4.2.1 + once: 1.4.0 + simple-concat: 1.0.1 + + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + sisteransi@1.0.5: {} smart-buffer@4.2.0: {} @@ -12500,6 +13667,14 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + stringify-entities@4.0.4: dependencies: character-entities-html4: 2.1.0 @@ -12548,12 +13723,31 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svg-arc-to-cubic-bezier@3.2.0: {} + tailwind-merge@3.5.0: {} tailwindcss@4.2.2: {} tapable@2.3.0: {} + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -12562,6 +13756,8 @@ snapshots: dependencies: any-promise: 1.3.0 + tiny-inflate@1.0.3: {} + tiny-invariant@1.3.3: {} tinybench@2.9.0: {} @@ -12581,6 +13777,8 @@ snapshots: tinyspy@4.0.4: {} + tmp@0.2.5: {} + toidentifier@1.0.1: {} token-types@6.1.2: @@ -12596,10 +13794,14 @@ snapshots: '@tokenlens/helpers': 1.3.1 '@tokenlens/models': 1.3.0 + tr46@0.0.3: {} + tr46@5.1.1: dependencies: punycode: 2.3.1 + traverse@0.3.9: {} + trim-lines@3.0.1: {} trough@2.2.0: {} @@ -12658,10 +13860,22 @@ snapshots: uint8array-extras@1.5.0: {} + undici-types@5.26.5: {} + undici-types@6.21.0: {} undici@7.24.4: {} + unicode-properties@1.4.1: + dependencies: + base64-js: 1.5.1 + unicode-trie: 2.0.0 + + unicode-trie@2.0.0: + dependencies: + pako: 0.2.9 + tiny-inflate: 1.0.3 + unicorn-magic@0.3.0: {} unified@11.0.5: @@ -12709,6 +13923,19 @@ snapshots: unpipe@1.0.0: {} + unzipper@0.10.14: + dependencies: + big-integer: 1.6.52 + binary: 0.3.0 + bluebird: 3.4.7 + buffer-indexof-polyfill: 1.0.2 + duplexer2: 0.1.4 + fstream: 1.0.12 + graceful-fs: 4.2.11 + listenercount: 1.0.1 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.4): dependencies: react: 19.2.4 @@ -12736,10 +13963,14 @@ snapshots: dependencies: react: 19.2.4 + util-deprecate@1.0.2: {} + uuid@11.1.0: {} uuid@13.0.0: {} + uuid@8.3.2: {} + vary@1.1.2: {} vaul@1.1.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): @@ -12783,6 +14014,12 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 + vite-compatible-readable-stream@3.6.1: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + vite-node@3.2.4(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: cac: 6.7.14 @@ -12885,6 +14122,8 @@ snapshots: web-streams-polyfill@3.3.3: {} + webidl-conversions@3.0.1: {} + webidl-conversions@7.0.0: {} whatwg-url@14.2.0: @@ -12892,6 +14131,11 @@ snapshots: tr46: 5.1.1 webidl-conversions: 7.0.0 + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + when@2.0.1: {} which-module@2.0.1: {} @@ -12905,6 +14149,10 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + winston@2.4.7: dependencies: async: 2.6.4 @@ -12930,12 +14178,16 @@ snapshots: ws@8.19.0: {} + xmlchars@2.2.0: {} + xtend@4.0.2: {} y18n@4.0.3: {} y18n@5.0.8: {} + yallist@4.0.0: {} + yaml@2.8.2: {} yargs-parser@18.1.3: @@ -12988,6 +14240,14 @@ snapshots: yoctocolors@2.1.2: {} + yoga-layout@3.2.1: {} + + zip-stream@4.1.1: + dependencies: + archiver-utils: 3.0.4 + compress-commons: 4.1.2 + readable-stream: 3.6.2 + zod-to-json-schema@3.25.1(zod@4.3.6): dependencies: zod: 4.3.6 From 61d7fce966b052af80b0a8583f1dd49b541a37d0 Mon Sep 17 00:00:00 2001 From: shanvit Date: Wed, 1 Apr 2026 13:17:14 +0530 Subject: [PATCH 02/12] feat(skill-reports): implement chart, csv, pdf, pptx, xlsx renderers --- packages/skills/reports/package.json | 10 + .../reports/src/renderers/chart.test.ts | 49 + .../skills/reports/src/renderers/chart.ts | 75 + .../skills/reports/src/renderers/csv.test.ts | 75 + packages/skills/reports/src/renderers/csv.ts | 66 + packages/skills/reports/src/renderers/pdf.ts | 155 ++ packages/skills/reports/src/renderers/pptx.ts | 158 ++ packages/skills/reports/src/renderers/xlsx.ts | 60 + .../skills/reports/src/templates/types.ts | 64 + pnpm-lock.yaml | 1316 ++++++++++++++++- 10 files changed, 2000 insertions(+), 28 deletions(-) create mode 100644 packages/skills/reports/src/renderers/chart.test.ts create mode 100644 packages/skills/reports/src/renderers/chart.ts create mode 100644 packages/skills/reports/src/renderers/csv.test.ts create mode 100644 packages/skills/reports/src/renderers/csv.ts create mode 100644 packages/skills/reports/src/renderers/pdf.ts create mode 100644 packages/skills/reports/src/renderers/pptx.ts create mode 100644 packages/skills/reports/src/renderers/xlsx.ts create mode 100644 packages/skills/reports/src/templates/types.ts diff --git a/packages/skills/reports/package.json b/packages/skills/reports/package.json index d4c1c62..5b0e7de 100644 --- a/packages/skills/reports/package.json +++ b/packages/skills/reports/package.json @@ -15,8 +15,18 @@ "build": "tsc", "check": "tsc --noEmit" }, + "dependencies": { + "@react-pdf/renderer": "^4.3.0", + "@sinclair/typebox": "^0.34.9", + "chart.js": "^4.4.9", + "chartjs-node-canvas": "^4.1.6", + "exceljs": "^4.4.0", + "pptxgenjs": "^3.12.0", + "react": "^19.1.0" + }, "devDependencies": { "@types/node": "^22.15.2", + "@types/react": "^19.1.2", "typescript": "^5.7.3" } } diff --git a/packages/skills/reports/src/renderers/chart.test.ts b/packages/skills/reports/src/renderers/chart.test.ts new file mode 100644 index 0000000..ee5787f --- /dev/null +++ b/packages/skills/reports/src/renderers/chart.test.ts @@ -0,0 +1,49 @@ +import assert from "node:assert/strict" +import { describe, it } from "node:test" +import { renderChart } from "./chart.js" + +describe("renderChart", () => { + it("renders a bar chart and returns a Buffer with PNG magic bytes", async () => { + const buf = await renderChart({ + type: "bar", + title: "Test Bar Chart", + labels: ["Jan", "Feb", "Mar"], + datasets: [ + { + label: "Sessions", + data: [10, 20, 15], + backgroundColor: "rgba(54, 162, 235, 0.5)", + }, + ], + }) + + assert.ok(buf instanceof Buffer, "result should be a Buffer") + // PNG magic bytes: \x89PNG + assert.equal(buf[0], 0x89) + assert.equal(buf[1], 0x50) // P + assert.equal(buf[2], 0x4e) // N + assert.equal(buf[3], 0x47) // G + }) + + it("renders a line chart", async () => { + const buf = await renderChart({ + type: "line", + title: "Line Chart", + labels: ["Q1", "Q2"], + datasets: [{ label: "Value", data: [5, 10] }], + }) + assert.ok(buf instanceof Buffer) + assert.ok(buf.length > 0) + }) + + it("renders a pie chart", async () => { + const buf = await renderChart({ + type: "pie", + title: "Pie Chart", + labels: ["A", "B"], + datasets: [{ label: "Share", data: [60, 40] }], + }) + assert.ok(buf instanceof Buffer) + assert.ok(buf.length > 0) + }) +}) diff --git a/packages/skills/reports/src/renderers/chart.ts b/packages/skills/reports/src/renderers/chart.ts new file mode 100644 index 0000000..cc4ef2e --- /dev/null +++ b/packages/skills/reports/src/renderers/chart.ts @@ -0,0 +1,75 @@ +import type { ChartConfiguration } from "chart.js" +import { ChartJSNodeCanvas } from "chartjs-node-canvas" + +/** Supported chart types. */ +export type ChartType = "bar" | "line" | "pie" + +/** A single dataset for a chart. */ +export interface ChartDataset { + /** Dataset label. */ + label: string + /** Data values. */ + data: number[] + /** Optional background color(s). */ + backgroundColor?: string | string[] + /** Optional border color(s). */ + borderColor?: string | string[] +} + +/** Input spec for a single chart. */ +export interface ChartSpec { + /** Chart type. */ + type: ChartType + /** Chart title. */ + title: string + /** X-axis labels. */ + labels: string[] + /** Datasets to plot. */ + datasets: ChartDataset[] +} + +const CANVAS_WIDTH = 800 +const CANVAS_HEIGHT = 400 + +/** + * Render a chart spec to a PNG or SVG buffer. + * + * @param spec - The chart spec to render. + * @param format - Output format: 'png' (default) or 'svg'. + * @returns A Buffer containing the rendered chart image. + */ +export const renderChart = async (spec: ChartSpec, format: "png" | "svg" = "png"): Promise => { + const canvasType = format === "svg" ? "svg" : undefined + const canvas = new ChartJSNodeCanvas({ + width: CANVAS_WIDTH, + height: CANVAS_HEIGHT, + type: canvasType, + backgroundColour: "white", + }) + + const config: ChartConfiguration = { + type: spec.type, + data: { + labels: spec.labels, + datasets: spec.datasets, + }, + options: { + plugins: { + title: { + display: true, + text: spec.title, + }, + legend: { + display: true, + }, + }, + responsive: false, + }, + } + + if (format === "svg") { + return canvas.renderToBufferSync(config, "image/svg+xml") + } + + return canvas.renderToBuffer(config) +} diff --git a/packages/skills/reports/src/renderers/csv.test.ts b/packages/skills/reports/src/renderers/csv.test.ts new file mode 100644 index 0000000..0e71b3c --- /dev/null +++ b/packages/skills/reports/src/renderers/csv.test.ts @@ -0,0 +1,75 @@ +import assert from "node:assert/strict" +import { describe, it } from "node:test" +import type { MonthlyReportData } from "../templates/types.js" +import { renderCsv } from "./csv.js" + +const baseData: MonthlyReportData = { + period: "March 2026", + totalSessions: 2, + totalMessages: 30, + totalToolCalls: 10, + sessions: [ + { sessionId: "s1", messageCount: 15, toolCallCount: 5, durationSeconds: 120 }, + { sessionId: "s2", messageCount: 15, toolCallCount: 5, durationSeconds: 90 }, + ], +} + +describe("renderCsv", () => { + it("returns a Buffer", async () => { + const buf = await renderCsv(baseData) + assert.ok(buf instanceof Buffer) + assert.ok(buf.length > 0) + }) + + it("contains correct summary headers and values", async () => { + const buf = await renderCsv(baseData) + const text = buf.toString("utf-8") + assert.ok(text.includes("label,value")) + assert.ok(text.includes("period,March 2026")) + assert.ok(text.includes("totalSessions,2")) + }) + + it("contains session table headers and session rows", async () => { + const buf = await renderCsv(baseData) + const text = buf.toString("utf-8") + assert.ok(text.includes("sessionId,messageCount,toolCallCount,durationSeconds")) + assert.ok(text.includes("s1,15,5,120")) + assert.ok(text.includes("s2,15,5,90")) + }) + + it("tables are separated by a blank line", async () => { + const buf = await renderCsv(baseData) + const text = buf.toString("utf-8") + assert.ok(text.includes("\n\n")) + }) + + it("escapes fields containing commas", async () => { + const data: MonthlyReportData = { + ...baseData, + period: "Jan, Feb 2026", + } + const buf = await renderCsv(data) + const text = buf.toString("utf-8") + assert.ok(text.includes('"Jan, Feb 2026"')) + }) + + it("escapes fields containing double-quotes", async () => { + const data: MonthlyReportData = { + ...baseData, + period: 'He said "hello"', + } + const buf = await renderCsv(data) + const text = buf.toString("utf-8") + assert.ok(text.includes('"He said ""hello"""')) + }) + + it("escapes fields containing newlines", async () => { + const data: MonthlyReportData = { + ...baseData, + period: "line1\nline2", + } + const buf = await renderCsv(data) + const text = buf.toString("utf-8") + assert.ok(text.includes('"line1\nline2"')) + }) +}) diff --git a/packages/skills/reports/src/renderers/csv.ts b/packages/skills/reports/src/renderers/csv.ts new file mode 100644 index 0000000..7b3fdb9 --- /dev/null +++ b/packages/skills/reports/src/renderers/csv.ts @@ -0,0 +1,66 @@ +import type { MonthlyReportData } from "../templates/types.js" + +/** + * Escape a single CSV field value. + * Wraps in double-quotes if the value contains a comma, newline, or double-quote. + * Inner double-quotes are escaped as "". + */ +const escapeCsvField = (value: string): string => { + if (value.includes(",") || value.includes("\n") || value.includes('"')) { + return `"${value.replace(/"/g, '""')}"` + } + return value +} + +/** + * Render a 2D array of string rows as a CSV block. + */ +const renderTable = (headers: string[], rows: string[][]): string => { + const lines: string[] = [headers.map(escapeCsvField).join(",")] + for (const row of rows) { + lines.push(row.map(escapeCsvField).join(",")) + } + return lines.join("\n") +} + +/** + * Render MonthlyReportData to a CSV buffer. + * + * Outputs two tables separated by a blank line: + * 1. Summary metrics (label, value) + * 2. Per-session breakdown + * + * @param data - The monthly report data to render. + * @returns A Buffer containing the UTF-8 encoded CSV content. + */ +export const renderCsv = async (data: MonthlyReportData): Promise => { + const sections: string[] = [] + + // Summary table + sections.push( + renderTable( + ["label", "value"], + [ + ["period", data.period], + ["totalSessions", String(data.totalSessions)], + ["totalMessages", String(data.totalMessages)], + ["totalToolCalls", String(data.totalToolCalls)], + ], + ), + ) + + // Sessions table + sections.push( + renderTable( + ["sessionId", "messageCount", "toolCallCount", "durationSeconds"], + data.sessions.map((s) => [ + s.sessionId, + String(s.messageCount), + String(s.toolCallCount), + String(s.durationSeconds), + ]), + ), + ) + + return Buffer.from(sections.join("\n\n"), "utf-8") +} diff --git a/packages/skills/reports/src/renderers/pdf.ts b/packages/skills/reports/src/renderers/pdf.ts new file mode 100644 index 0000000..65deb4a --- /dev/null +++ b/packages/skills/reports/src/renderers/pdf.ts @@ -0,0 +1,155 @@ +import ReactPDF from "@react-pdf/renderer" +import React from "react" +import type { MonthlyReportData, RenderOpts } from "../templates/types.js" +import { renderChart } from "./chart.js" + +const { Document, Page, View, Text, Image, StyleSheet, renderToBuffer } = ReactPDF + +const styles = StyleSheet.create({ + page: { + padding: 40, + fontFamily: "Helvetica", + fontSize: 11, + color: "#222", + }, + title: { + fontSize: 20, + fontFamily: "Helvetica-Bold", + marginBottom: 4, + }, + subtitle: { + fontSize: 13, + marginBottom: 16, + color: "#555", + }, + sectionHeading: { + fontSize: 13, + fontFamily: "Helvetica-Bold", + marginBottom: 6, + marginTop: 14, + }, + tableRow: { + flexDirection: "row", + borderBottomWidth: 0.5, + borderBottomColor: "#ccc", + paddingVertical: 3, + }, + tableHeader: { + fontFamily: "Helvetica-Bold", + }, + cell: { + flex: 1, + }, + chart: { + width: 480, + height: 240, + marginBottom: 8, + }, +}) + +/** Column definitions for summary metrics. */ +const METRIC_HEADERS = ["Label", "Value"] + +/** Build summary metrics rows from report data. */ +const metricRows = (data: MonthlyReportData): [string, string][] => [ + ["Period", data.period], + ["Total Sessions", String(data.totalSessions)], + ["Total Messages", String(data.totalMessages)], + ["Total Tool Calls", String(data.totalToolCalls)], +] + +/** Build a default bar chart spec from report data for the sessions overview. */ +const buildSessionsChartSpec = (data: MonthlyReportData) => ({ + type: "bar" as const, + title: "Sessions Overview", + labels: data.sessions.map((s) => s.sessionId), + datasets: [ + { + label: "Messages", + data: data.sessions.map((s) => s.messageCount), + backgroundColor: "rgba(54, 162, 235, 0.7)", + }, + { + label: "Tool Calls", + data: data.sessions.map((s) => s.toolCallCount), + backgroundColor: "rgba(255, 99, 132, 0.7)", + }, + ], +}) + +/** + * Render MonthlyReportData to a PDF buffer using @react-pdf/renderer. + * + * Layout: + * - Title + period + summary metrics table + * - Sessions overview chart (embedded PNG) + * - Per-session breakdown table + * + * @param data - The monthly report data to render. + * @param opts - Optional render options (format, outputPath). + * @returns A Buffer containing the PDF binary content. + */ +export const renderPdf = async (data: MonthlyReportData, _opts?: RenderOpts): Promise => { + // Pre-render chart to PNG buffer and encode as base64 data URI + const chartBuf = await renderChart(buildSessionsChartSpec(data)) + const chartDataUri = `data:image/png;base64,${chartBuf.toString("base64")}` + + const doc = React.createElement( + Document, + null, + React.createElement( + Page, + { size: "A4", style: styles.page }, + // Title + React.createElement(Text, { style: styles.title }, "Monthly Report"), + React.createElement(Text, { style: styles.subtitle }, data.period), + // Summary metrics + React.createElement(Text, { style: styles.sectionHeading }, "Summary"), + React.createElement( + View, + null, + React.createElement( + View, + { style: { ...styles.tableRow, ...styles.tableHeader } }, + ...METRIC_HEADERS.map((h) => React.createElement(Text, { key: h, style: styles.cell }, h)), + ), + ...metricRows(data).map(([label, value]) => + React.createElement( + View, + { key: label, style: styles.tableRow }, + React.createElement(Text, { style: styles.cell }, label), + React.createElement(Text, { style: styles.cell }, value), + ), + ), + ), + // Chart section + React.createElement(Text, { style: styles.sectionHeading }, "Sessions Overview"), + React.createElement(Image, { src: chartDataUri, style: styles.chart }), + // Sessions table + React.createElement(Text, { style: styles.sectionHeading }, "Session Breakdown"), + React.createElement( + View, + null, + React.createElement( + View, + { style: { ...styles.tableRow, ...styles.tableHeader } }, + ...["Session ID", "Messages", "Tool Calls", "Duration (s)"].map((h) => + React.createElement(Text, { key: h, style: styles.cell }, h), + ), + ), + ...data.sessions.map((s) => + React.createElement( + View, + { key: s.sessionId, style: styles.tableRow }, + React.createElement(Text, { style: styles.cell }, s.sessionId), + React.createElement(Text, { style: styles.cell }, String(s.messageCount)), + React.createElement(Text, { style: styles.cell }, String(s.toolCallCount)), + React.createElement(Text, { style: styles.cell }, String(s.durationSeconds)), + ), + ), + ), + ), + ) + + return renderToBuffer(doc) +} diff --git a/packages/skills/reports/src/renderers/pptx.ts b/packages/skills/reports/src/renderers/pptx.ts new file mode 100644 index 0000000..499e720 --- /dev/null +++ b/packages/skills/reports/src/renderers/pptx.ts @@ -0,0 +1,158 @@ +import { createRequire } from "node:module" +import type { MonthlyReportData, RenderOpts } from "../templates/types.js" +import { renderChart } from "./chart.js" + +const require = createRequire(import.meta.url) +// pptxgenjs ships a CJS bundle; load it via require to get the constructor +const PptxGenJS = require("pptxgenjs") as new () => { + layout: string + addSlide(): { + addText(text: string, opts: object): void + addTable(rows: object[], opts: object): void + addImage(opts: object): void + } + write(opts: { outputType: string }): Promise +} + +/** Build a sessions overview chart spec from report data. */ +const buildSessionsChartSpec = (data: MonthlyReportData) => ({ + type: "bar" as const, + title: "Sessions Overview", + labels: data.sessions.map((s) => s.sessionId), + datasets: [ + { + label: "Messages", + data: data.sessions.map((s) => s.messageCount), + backgroundColor: "rgba(54, 162, 235, 0.7)", + }, + { + label: "Tool Calls", + data: data.sessions.map((s) => s.toolCallCount), + backgroundColor: "rgba(255, 99, 132, 0.7)", + }, + ], +}) + +/** + * Render MonthlyReportData to a PowerPoint (PPTX) buffer using pptxgenjs. + * + * Slide layout: + * 1. Title slide — report title + period + * 2. Summary metrics slide — label/value table + * 3. Sessions overview chart slide — embedded PNG + * 4. Session breakdown table slide + * + * @param data - The monthly report data to render. + * @param opts - Optional render options (format, outputPath). + * @returns A Buffer containing the PPTX binary content. + */ +export const renderPptx = async (data: MonthlyReportData, _opts?: RenderOpts): Promise => { + const pptx = new PptxGenJS() + pptx.layout = "LAYOUT_16x9" + + // --- Slide 1: Title --- + const titleSlide = pptx.addSlide() + titleSlide.addText("Monthly Report", { + x: 0.5, + y: 1.5, + w: 9, + h: 1.2, + fontSize: 36, + bold: true, + align: "center", + }) + titleSlide.addText(data.period, { + x: 0.5, + y: 2.9, + w: 9, + h: 0.7, + fontSize: 24, + align: "center", + color: "555555", + }) + + // --- Slide 2: Summary Metrics --- + const metricsSlide = pptx.addSlide() + metricsSlide.addText("Summary Metrics", { + x: 0.5, + y: 0.3, + w: 9, + h: 0.6, + fontSize: 20, + bold: true, + }) + metricsSlide.addTable( + [ + [ + { text: "Label", options: { bold: true } }, + { text: "Value", options: { bold: true } }, + ], + [{ text: "Period" }, { text: data.period }], + [{ text: "Total Sessions" }, { text: String(data.totalSessions) }], + [{ text: "Total Messages" }, { text: String(data.totalMessages) }], + [{ text: "Total Tool Calls" }, { text: String(data.totalToolCalls) }], + ], + { x: 0.5, y: 1.1, w: 9, colW: [4.5, 4.5], fontSize: 14 }, + ) + + // --- Slide 3: Chart --- + const chartBuf = await renderChart(buildSessionsChartSpec(data)) + const chartBase64 = chartBuf.toString("base64") + + const chartSlide = pptx.addSlide() + chartSlide.addText("Sessions Overview", { + x: 0.5, + y: 0.3, + w: 9, + h: 0.6, + fontSize: 20, + bold: true, + }) + chartSlide.addImage({ + data: `image/png;base64,${chartBase64}`, + x: 0.5, + y: 1.1, + w: 9, + h: 4.5, + }) + + // --- Slide 4: Session Breakdown Table --- + const tableSlide = pptx.addSlide() + tableSlide.addText("Session Breakdown", { + x: 0.5, + y: 0.3, + w: 9, + h: 0.6, + fontSize: 20, + bold: true, + }) + + type TableRow = { text?: string; options?: { bold?: boolean } }[] + const tableRows: TableRow[] = [ + [ + { text: "Session ID", options: { bold: true } }, + { text: "Messages", options: { bold: true } }, + { text: "Tool Calls", options: { bold: true } }, + { text: "Duration (s)", options: { bold: true } }, + ], + ...data.sessions.map( + (s): TableRow => [ + { text: s.sessionId }, + { text: String(s.messageCount) }, + { text: String(s.toolCallCount) }, + { text: String(s.durationSeconds) }, + ], + ), + ] + + tableSlide.addTable(tableRows, { + x: 0.5, + y: 1.1, + w: 9, + colW: [2.5, 2, 2, 2.5], + fontSize: 12, + }) + + const result = await pptx.write({ outputType: "nodebuffer" }) + return result as Buffer +} diff --git a/packages/skills/reports/src/renderers/xlsx.ts b/packages/skills/reports/src/renderers/xlsx.ts new file mode 100644 index 0000000..4c57fa6 --- /dev/null +++ b/packages/skills/reports/src/renderers/xlsx.ts @@ -0,0 +1,60 @@ +import ExcelJS from "exceljs" +import type { MonthlyReportData, RenderOpts } from "../templates/types.js" + +/** + * Render MonthlyReportData to an Excel (XLSX) buffer using exceljs. + * + * Sheet layout: + * - Sheet "Metrics": columns label, value (summary metrics) + * - Sheet "Sessions": columns sessionId, messageCount, toolCallCount, durationSeconds + * + * @param data - The monthly report data to render. + * @param opts - Optional render options (format, outputPath). + * @returns A Buffer containing the XLSX binary content. + */ +export const renderXlsx = async (data: MonthlyReportData, _opts?: RenderOpts): Promise => { + const workbook = new ExcelJS.Workbook() + + // --- Sheet 1: Metrics --- + const metricsSheet = workbook.addWorksheet("Metrics") + metricsSheet.columns = [ + { header: "label", key: "label", width: 24 }, + { header: "value", key: "value", width: 20 }, + { header: "unit", key: "unit", width: 16 }, + { header: "change", key: "change", width: 16 }, + ] + // Style header row + const metricsHeader = metricsSheet.getRow(1) + metricsHeader.font = { bold: true } + metricsHeader.commit() + + // Summary rows + metricsSheet.addRow({ label: "period", value: data.period, unit: "", change: "" }) + metricsSheet.addRow({ label: "totalSessions", value: data.totalSessions, unit: "sessions", change: "" }) + metricsSheet.addRow({ label: "totalMessages", value: data.totalMessages, unit: "messages", change: "" }) + metricsSheet.addRow({ label: "totalToolCalls", value: data.totalToolCalls, unit: "calls", change: "" }) + + // --- Sheet 2: Sessions --- + const sessionsSheet = workbook.addWorksheet("Sessions") + sessionsSheet.columns = [ + { header: "sessionId", key: "sessionId", width: 28 }, + { header: "messageCount", key: "messageCount", width: 16 }, + { header: "toolCallCount", key: "toolCallCount", width: 16 }, + { header: "durationSeconds", key: "durationSeconds", width: 18 }, + ] + const sessionsHeader = sessionsSheet.getRow(1) + sessionsHeader.font = { bold: true } + sessionsHeader.commit() + + for (const s of data.sessions) { + sessionsSheet.addRow({ + sessionId: s.sessionId, + messageCount: s.messageCount, + toolCallCount: s.toolCallCount, + durationSeconds: s.durationSeconds, + }) + } + + const arrayBuffer = await workbook.xlsx.writeBuffer() + return Buffer.from(arrayBuffer) +} diff --git a/packages/skills/reports/src/templates/types.ts b/packages/skills/reports/src/templates/types.ts new file mode 100644 index 0000000..4dd1935 --- /dev/null +++ b/packages/skills/reports/src/templates/types.ts @@ -0,0 +1,64 @@ +/** + * Core types for the reports skill template system. + */ + +/** Supported output formats for report rendering. */ +export type ReportFormat = "pdf" | "pptx" | "xlsx" + +/** Options passed to a template renderer. */ +export interface RenderOpts { + /** Output format requested by the caller. */ + format: ReportFormat + /** Absolute path where the rendered file should be written. */ + outputPath: string +} + +/** + * A report template that can render structured data into one or more formats. + * + * @typeParam T - The validated data shape this template accepts. + */ +export interface ReportTemplate { + /** Unique machine-readable name used to look up the template. */ + name: string + /** Human-readable title shown in listings. */ + title: string + /** Formats this template supports. */ + formats: ReportFormat[] + /** + * Validate and parse raw input data into the typed shape T. + * Should throw a descriptive error on invalid input. + */ + parse: (raw: unknown) => T + /** + * Render the report data to the requested format and write the result to outputPath. + * Returns the absolute path of the written file. + */ + render: (data: T, opts: RenderOpts) => Promise +} + +/** One row of session-level metrics for a monthly report. */ +export interface SessionMetricRow { + /** Session identifier. */ + sessionId: string + /** Total number of messages in the session. */ + messageCount: number + /** Total tool calls made during the session. */ + toolCallCount: number + /** Session duration in seconds. */ + durationSeconds: number +} + +/** Aggregated data driving a monthly report. */ +export interface MonthlyReportData { + /** Report period label, e.g. "March 2026". */ + period: string + /** Total sessions started in the period. */ + totalSessions: number + /** Total messages exchanged in the period. */ + totalMessages: number + /** Total tool calls in the period. */ + totalToolCalls: number + /** Per-session breakdown. */ + sessions: SessionMetricRow[] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8272f05..bbd07db 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -672,10 +672,35 @@ importers: version: 5.9.3 packages/skills/reports: + dependencies: + '@react-pdf/renderer': + specifier: ^4.3.0 + version: 4.3.2(react@19.2.4) + '@sinclair/typebox': + specifier: ^0.34.9 + version: 0.34.48 + chart.js: + specifier: ^4.4.9 + version: 4.5.1 + chartjs-node-canvas: + specifier: ^4.1.6 + version: 4.1.6(chart.js@4.5.1) + exceljs: + specifier: ^4.4.0 + version: 4.4.0 + pptxgenjs: + specifier: ^3.12.0 + version: 3.12.0 + react: + specifier: ^19.1.0 + version: 19.2.4 devDependencies: '@types/node': specifier: ^22.15.2 version: 22.19.15 + '@types/react': + specifier: ^19.1.2 + version: 19.2.14 typescript: specifier: ^5.7.3 version: 5.9.3 @@ -1192,6 +1217,12 @@ packages: cpu: [x64] os: [win32] + '@fast-csv/format@4.3.5': + resolution: {integrity: sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==} + + '@fast-csv/parse@4.3.6': + resolution: {integrity: sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==} + '@floating-ui/core@1.7.5': resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} @@ -1420,6 +1451,13 @@ packages: '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + '@kurkle/color@0.3.4': + resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} + + '@mapbox/node-pre-gyp@1.0.11': + resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + hasBin: true + '@mariozechner/clipboard-darwin-arm64@0.3.2': resolution: {integrity: sha512-uBf6K7Je1ihsgvmWxA8UCGCeI+nbRVRXoarZdLjl6slz94Zs1tNKFZqx7aCI5O1i3e0B6ja82zZ06BWrl0MCVw==} engines: {node: '>= 10'} @@ -2421,6 +2459,49 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + '@react-pdf/fns@3.1.2': + resolution: {integrity: sha512-qTKGUf0iAMGg2+OsUcp9ffKnKi41RukM/zYIWMDJ4hRVYSr89Q7e3wSDW/Koqx3ea3Uy/z3h2y3wPX6Bdfxk6g==} + + '@react-pdf/font@4.0.4': + resolution: {integrity: sha512-8YtgGtL511txIEc9AjiilpZ7yjid8uCd8OGUl6jaL3LIHnrToUupSN4IzsMQpVTCMYiDLFnDNQzpZsOYtRS/Pg==} + + '@react-pdf/image@3.0.4': + resolution: {integrity: sha512-z0ogVQE0bKqgXQ5smgzIU857rLV7bMgVdrYsu3UfXDDLSzI7QPvzf6MFTFllX6Dx2rcsF13E01dqKPtJEM799g==} + + '@react-pdf/layout@4.4.2': + resolution: {integrity: sha512-gNu2oh8MiGR+NJZYTJ4c4q0nWCESBI6rKFiodVhE7OeVAjtzZzd6l65wsN7HXdWJqOZD3ttD97iE+tf5SOd/Yg==} + + '@react-pdf/pdfkit@4.1.0': + resolution: {integrity: sha512-Wm/IOAv0h/U5Ra94c/PltFJGcpTUd/fwVMVeFD6X9tTTPCttIwg0teRG1Lqq617J8K4W7jpL/B0HTH0mjp3QpQ==} + + '@react-pdf/png-js@3.0.0': + resolution: {integrity: sha512-eSJnEItZ37WPt6Qv5pncQDxLJRK15eaRwPT+gZoujP548CodenOVp49GST8XJvKMFt9YqIBzGBV/j9AgrOQzVA==} + + '@react-pdf/primitives@4.1.1': + resolution: {integrity: sha512-IuhxYls1luJb7NUWy6q5avb1XrNaVj9bTNI40U9qGRuS6n7Hje/8H8Qi99Z9UKFV74bBP3DOf3L1wV2qZVgVrQ==} + + '@react-pdf/reconciler@2.0.0': + resolution: {integrity: sha512-7zaPRujpbHSmCpIrZ+b9HSTJHthcVZzX0Wx7RzvQGsGBUbHP4p6s5itXrAIOuQuPvDepoHGNOvf6xUuMVvdoyw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@react-pdf/render@4.3.2': + resolution: {integrity: sha512-el5KYM1sH/PKcO4tRCIm8/AIEmhtraaONbwCrBhFdehoGv6JtgnXiMxHGAvZbI5kEg051GbyP+XIU6f6YbOu6Q==} + + '@react-pdf/renderer@4.3.2': + resolution: {integrity: sha512-EhPkj35gO9rXIyyx29W3j3axemvVY5RigMmlK4/6Ku0pXB8z9PEE/sz4ZBOShu2uot6V4xiCR3aG+t9IjJJlBQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@react-pdf/stylesheet@6.1.2': + resolution: {integrity: sha512-E3ftGRYUQGKiN3JOgtGsLDo0hGekA6dmkmi/MYACytmPTKxQRBSO3126MebmCq+t1rgU9uRlREIEawJ+8nzSbw==} + + '@react-pdf/textkit@6.1.0': + resolution: {integrity: sha512-sFlzDC9CDFrJsnL3B/+NHrk9+Advqk7iJZIStiYQDdskbow8GF/AGYrpIk+vWSnh35YxaGbHkqXq53XOxnyrjQ==} + + '@react-pdf/types@2.9.2': + resolution: {integrity: sha512-dufvpKId9OajLLbgn9q7VLUmyo1Jf+iyGk2ZHmCL8nIDtL8N1Ejh9TH7+pXXrR0tdie1nmnEb5Bz9U7g4hI4/g==} + '@remirror/core-constants@3.0.0': resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} @@ -3353,6 +3434,12 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@14.18.63': + resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==} + + '@types/node@18.19.130': + resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} + '@types/node@22.19.15': resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} @@ -3463,6 +3550,12 @@ packages: resolution: {integrity: sha512-JtCjTvbBVNP43mmuCqhSXk16XSKE5L4/4wbVFJsz6K2syfplNUnsZxHxnqJ0dQoe3Fy70V09uWI29uaXkNdjrg==} engines: {node: '>=16.0.0'} + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + + abs-svg-path@0.1.1: + resolution: {integrity: sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==} + accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} @@ -3472,6 +3565,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -3508,6 +3605,26 @@ packages: any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + aproba@2.1.0: + resolution: {integrity: sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==} + + archiver-utils@2.1.0: + resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} + engines: {node: '>= 6'} + + archiver-utils@3.0.4: + resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==} + engines: {node: '>= 10'} + + archiver@5.3.2: + resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} + engines: {node: '>= 10'} + + are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -3532,6 +3649,9 @@ packages: async@3.2.3: resolution: {integrity: sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==} + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -3555,6 +3675,10 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} + base64-js@0.0.8: + resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==} + engines: {node: '>= 0.4'} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -3640,9 +3764,25 @@ packages: zod: optional: true + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + + big-integer@1.6.52: + resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} + engines: {node: '>=0.6'} + bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + binary@0.3.0: + resolution: {integrity: sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + bluebird@3.4.7: + resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==} + bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} @@ -3653,10 +3793,22 @@ packages: bowser@2.14.1: resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + brace-expansion@1.1.13: + resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} + + brace-expansion@2.0.3: + resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==} + brace-expansion@5.0.4: resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} engines: {node: 18 || 20 || >=22} + brotli@1.3.3: + resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} + + browserify-zlib@0.2.0: + resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} + bson@7.2.0: resolution: {integrity: sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ==} engines: {node: '>=20.19.0'} @@ -3667,6 +3819,17 @@ packages: buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + buffer-indexof-polyfill@1.0.2: + resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==} + engines: {node: '>=0.10'} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffers@0.1.1: + resolution: {integrity: sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==} + engines: {node: '>=0.2.0'} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -3690,6 +3853,10 @@ packages: caniuse-lite@1.0.30001780: resolution: {integrity: sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==} + canvas@2.11.2: + resolution: {integrity: sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==} + engines: {node: '>=6'} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -3697,6 +3864,9 @@ packages: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} + chainsaw@0.1.0: + resolution: {integrity: sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -3717,6 +3887,15 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + chart.js@4.5.1: + resolution: {integrity: sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==} + engines: {pnpm: '>=8'} + + chartjs-node-canvas@4.1.6: + resolution: {integrity: sha512-UQJbPWrvqB/FoLclGA9BaLQmZbzSYlujF4w8NZd6Xzb+sqgACBb2owDX6m7ifCXLjUW5Nz0Qx0qqrTtQkkSoYw==} + peerDependencies: + chart.js: ^3.5.1 + check-error@2.1.3: resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} @@ -3729,6 +3908,10 @@ packages: chevrotain@11.1.2: resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==} + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -3753,6 +3936,10 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -3770,6 +3957,13 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + colors@1.0.3: resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} engines: {node: '>=0.1.90'} @@ -3793,9 +3987,19 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + compress-commons@4.1.2: + resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} + engines: {node: '>= 10'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + content-disposition@1.0.1: resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} engines: {node: '>=18'} @@ -3812,6 +4016,9 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cors@2.8.6: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} @@ -3826,6 +4033,15 @@ packages: resolution: {integrity: sha512-/2yieBqvMcRj8McNzkycjW2v3OIUOibBfd2dLEJ0nWts8NobAxwiyw9phVNS6oDL8x8tz9F7uNVFEVpJncQpeA==} engines: {node: '>=8.0.0'} + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@4.0.3: + resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} + engines: {node: '>= 10'} + crelt@1.0.6: resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} @@ -3833,6 +4049,9 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} @@ -4054,6 +4273,10 @@ packages: decode-named-character-reference@1.3.0: resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + decompress-response@4.2.1: + resolution: {integrity: sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==} + engines: {node: '>=8'} + deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} @@ -4076,6 +4299,9 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + denque@2.1.0: resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} engines: {node: '>=0.10'} @@ -4098,6 +4324,9 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dfa@1.2.0: + resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==} + diff@8.0.3: resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} engines: {node: '>=0.3.1'} @@ -4120,6 +4349,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} @@ -4139,6 +4371,9 @@ packages: embla-carousel@8.6.0: resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4239,6 +4474,10 @@ packages: eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + eventsource-parser@3.0.6: resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} engines: {node: '>=18.0.0'} @@ -4247,6 +4486,10 @@ packages: resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} engines: {node: '>=18.0.0'} + exceljs@4.4.0: + resolution: {integrity: sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg==} + engines: {node: '>=8.3.0'} + execa@9.6.1: resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} engines: {node: ^18.19.0 || >=20.5.0} @@ -4271,6 +4514,10 @@ packages: resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} engines: {node: '> 0.1.90'} + fast-csv@4.3.6: + resolution: {integrity: sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==} + engines: {node: '>=10.0.0'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -4332,6 +4579,9 @@ packages: debug: optional: true + fontkit@2.0.4: + resolution: {integrity: sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==} + form-data@4.0.5: resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} @@ -4362,14 +4612,34 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + fstream@1.0.12: + resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==} + engines: {node: '>=0.6'} + deprecated: This package is no longer supported. + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + gaxios@7.1.4: resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} engines: {node: '>=18'} @@ -4420,6 +4690,10 @@ packages: resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} engines: {node: 18 || 20 || >=22} + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + google-auth-library@10.6.2: resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} engines: {node: '>=18'} @@ -4450,6 +4724,9 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -4511,6 +4788,12 @@ packages: resolution: {integrity: sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==} engines: {node: ^20.17.0 || >=22.9.0} + hsl-to-hex@1.0.0: + resolution: {integrity: sha512-K6GVpucS5wFf44X0h2bLVRDsycgJmf9FF2elg+CrqD8GcFU8c6vYhgXn8NjUkFCwj+xDFb70qgLbTUm6sxwPmA==} + + hsl-to-rgb-for-reals@1.1.1: + resolution: {integrity: sha512-LgOWAkrN0rFaQpfdWBQlv/VhkOxb5AsBjk6NQVx4yEzWS923T07X0M1Y0VNko2H52HeSpZrZNNMJ0aFqsdVzQg==} + html-url-attributes@3.0.1: resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} @@ -4525,14 +4808,24 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + https@1.0.0: + resolution: {integrity: sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==} + human-signals@8.0.1: resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} engines: {node: '>=18.18.0'} + hyphen@1.14.1: + resolution: {integrity: sha512-kvL8xYl5QMTh+LwohVN72ciOxC0OEV79IPdJSTwEXok9y9QHebXGdFgrED4sWfiax/ODx++CAMk3hMy4XPJPOw==} + iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -4548,10 +4841,22 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} + image-size@1.2.1: + resolution: {integrity: sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==} + engines: {node: '>=16.x'} + hasBin: true + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + inflection@1.13.4: resolution: {integrity: sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==} engines: {'0': node >= 0.4.0} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -4582,6 +4887,9 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + is-core-module@2.16.1: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} @@ -4621,12 +4929,21 @@ packages: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + jay-peg@1.1.1: + resolution: {integrity: sha512-D62KEuBxz/ip2gQKOEhk/mx14o7eiFRaU+VNNSP4MOiIkwb/D6B3G1Mfas7C/Fit8EsSV2/IWjZElx/Gs6A4ww==} + jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -4660,6 +4977,9 @@ packages: resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} engines: {node: '>=12', npm: '>=6'} + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + jwa@2.0.1: resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} @@ -4694,6 +5014,13 @@ packages: layout-base@2.0.1: resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -4768,12 +5095,18 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} + linebreak@1.1.0: + resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} + linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} linkifyjs@4.3.2: resolution: {integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==} + listenercount@1.0.1: + resolution: {integrity: sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -4787,15 +5120,37 @@ packages: lodash.defaults@4.2.0: resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + lodash.difference@4.5.0: + resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + + lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + + lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + + lodash.groupby@4.6.0: + resolution: {integrity: sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==} + lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} lodash.isboolean@3.0.3: resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + + lodash.isfunction@3.0.9: + resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} + lodash.isinteger@4.0.4: resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + lodash.isnil@4.0.0: + resolution: {integrity: sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==} + lodash.isnumber@3.0.3: resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} @@ -4805,9 +5160,18 @@ packages: lodash.isstring@4.0.1: resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + lodash.isundefined@3.0.1: + resolution: {integrity: sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==} + lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + lodash.union@4.6.0: + resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + lodash@4.17.23: resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} @@ -4849,6 +5213,10 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + markdown-it@14.1.1: resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} hasBin: true @@ -4926,6 +5294,9 @@ packages: mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + media-engine@1.0.3: + resolution: {integrity: sha512-aa5tG6sDoK+k70B9iEX1NeyfT8ObCKhNDs6lJVpwF6r8vhUfuKMslIcirq6HIUYuuUYLefcEQOn9bSBOvawtwg==} + media-typer@1.1.0: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} @@ -5072,21 +5443,49 @@ packages: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} + mimic-response@2.1.0: + resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==} + engines: {node: '>=8'} + minimatch@10.2.4: resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} engines: {node: 18 || 20 || >=22} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + mlly@1.8.1: resolution: {integrity: sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==} @@ -5224,6 +5623,15 @@ packages: engines: {node: '>=10.5.0'} deprecated: Use your platform's native DOMException instead + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-fetch@3.3.2: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -5233,10 +5641,26 @@ packages: engines: {node: '>=0.1.97'} os: [linux, darwin, freebsd, win32, smartos, sunos] + nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-svg-path@1.1.0: + resolution: {integrity: sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==} + npm-run-path@6.0.0: resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} engines: {node: '>=18'} + npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -5312,6 +5736,12 @@ packages: package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + parse-database-url@0.3.0: resolution: {integrity: sha512-YRxDoVBAUk3ksGF9pud+aqWwXmThZzhX9Z1PPxKU03BB3/gu2RcgyMA4rktMYhkIJ9KxwW7lIj00U+TSNz80wg==} engines: {node: '>= 0.6'} @@ -5323,6 +5753,9 @@ packages: resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} engines: {node: '>=18'} + parse-svg-path@0.1.2: + resolution: {integrity: sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==} + parse5-htmlparser2-tree-adapter@6.0.1: resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} @@ -5353,6 +5786,10 @@ packages: resolution: {integrity: sha512-qdVgY8KXmVdJZRSS1JdEPOKPdTiEK/pi0RkcT2sw1RhXxohdujUlJFPuS1TSkevZ9vzd3ZlL7ULl1MHGTApKzQ==} engines: {node: '>=14.0.0'} + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -5431,6 +5868,9 @@ packages: points-on-path@0.2.1: resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + postcss@8.4.31: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} @@ -5455,10 +5895,16 @@ packages: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} + pptxgenjs@3.12.0: + resolution: {integrity: sha512-ZozkYKWb1MoPR4ucw3/aFYlHkVIJxo9czikEclcUVnS4Iw/M+r+TEwdlB3fyAWO9JY1USxJDt0Y0/r15IR/RUA==} + pretty-ms@9.3.0: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + prompt@1.3.0: resolution: {integrity: sha512-ZkaRWtaLBZl7KKAKndKYUL8WqNT+cQHKRZnT4RYYms48jQkFw3rrBL+/N5K/KtdEveHkxs982MX2BkDKub2ZMg==} engines: {node: '>= 6.0.0'} @@ -5560,6 +6006,9 @@ packages: resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} engines: {node: '>=0.6'} + queue@6.0.2: + resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} + radix-ui@1.4.3: resolution: {integrity: sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==} peerDependencies: @@ -5664,6 +6113,16 @@ packages: resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} engines: {node: '>=0.8'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + recharts-scale@0.4.5: resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} @@ -5752,6 +6211,9 @@ packages: engines: {node: '>= 0.4'} hasBin: true + restructure@3.0.2: + resolution: {integrity: sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==} + retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -5764,6 +6226,16 @@ packages: resolution: {integrity: sha512-xcBILK2pA9oh4SiinPEZfhP8HfrB/ha+a2fTMyl7Om2WjlDVrOQy99N2MXXlUHqGJz4qEu2duXxHJjDWuK/0xg==} engines: {node: '>= 0.4.0'} + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} @@ -5788,12 +6260,22 @@ packages: rw@1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + saxes@5.0.1: + resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} + engines: {node: '>=10'} + + scheduler@0.25.0-rc-603e6108-20241029: + resolution: {integrity: sha512-pFwF6H1XrSdYYNLfOcGlM28/j8CGLu8IvdrxqhjWULe2bPcKiKW4CV+OWqR/9fT52mywx65l7ysNkjLKBda7eA==} + scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} @@ -5801,6 +6283,10 @@ packages: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + semver@7.7.4: resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} @@ -5820,6 +6306,9 @@ packages: set-cookie-parser@3.0.1: resolution: {integrity: sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==} + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -5864,6 +6353,15 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@3.1.1: + resolution: {integrity: sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==} + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -5933,6 +6431,12 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} @@ -5992,6 +6496,9 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svg-arc-to-cubic-bezier@3.2.0: + resolution: {integrity: sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g==} + tailwind-merge@3.5.0: resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} @@ -6002,6 +6509,15 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -6009,6 +6525,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -6038,6 +6557,10 @@ packages: resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} engines: {node: '>=14.0.0'} + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -6049,10 +6572,16 @@ packages: tokenlens@1.3.1: resolution: {integrity: sha512-7oxmsS5PNCX3z+b+z07hL5vCzlgHKkCGrEQjQmWl5l+v5cUrtL7S1cuST4XThaL1XyjbTX8J5hfP0cjDJRkaLA==} + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@5.1.1: resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} engines: {node: '>=18'} + traverse@0.3.9: + resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==} + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -6120,6 +6649,9 @@ packages: resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} engines: {node: '>=18'} + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -6127,6 +6659,12 @@ packages: resolution: {integrity: sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==} engines: {node: '>=20.18.1'} + unicode-properties@1.4.1: + resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} + + unicode-trie@2.0.0: + resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} + unicorn-magic@0.3.0: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} @@ -6159,6 +6697,9 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unzipper@0.10.14: + resolution: {integrity: sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==} + use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -6195,6 +6736,9 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + uuid@11.1.0: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true @@ -6203,6 +6747,10 @@ packages: resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} hasBin: true + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -6225,6 +6773,10 @@ packages: victory-vendor@36.9.2: resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + vite-compatible-readable-stream@3.6.1: + resolution: {integrity: sha512-t20zYkrSf868+j/p31cRIGN28Phrjm3nRSLR2fyc2tiWi4cZGVdv68yNlwnIINTkMTmPoMiSlc0OadaO7DXZaQ==} + engines: {node: '>= 6'} + vite-node@3.2.4: resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -6328,6 +6880,9 @@ packages: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} @@ -6336,6 +6891,9 @@ packages: resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} engines: {node: '>=18'} + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + when@2.0.1: resolution: {integrity: sha512-h0l57vFJ4YQe1/U+C+oqBfAoopxXABUm6VqWM0x2gg4pARru4IUWo/PAxyawWgbGtndXrZbA41EzsfxacZVEXQ==} @@ -6352,6 +6910,9 @@ packages: engines: {node: '>=8'} hasBin: true + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + winston@2.4.7: resolution: {integrity: sha512-vLB4BqzCKDnnZH9PHGoS2ycawueX4HLqENXQitvFHczhgW2vFpSOn31LZtVr1KU8YTw7DS4tM+cqyovxo8taVg==} engines: {node: '>= 0.10.0'} @@ -6379,6 +6940,9 @@ packages: utf-8-validate: optional: true + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -6390,6 +6954,9 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yaml@2.8.2: resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} @@ -6426,6 +6993,13 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} + yoga-layout@3.2.1: + resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} + + zip-stream@4.1.1: + resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} + engines: {node: '>= 10'} + zod-to-json-schema@3.25.1: resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} peerDependencies: @@ -6912,14 +7486,14 @@ snapshots: nanostores: 1.2.0 zod: 4.3.6 - '@better-auth/drizzle-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/drizzle-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/kysely-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13)': + '@better-auth/kysely-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 kysely: 0.28.13 @@ -6929,25 +7503,25 @@ snapshots: '@better-auth/utils': 0.3.1 kysely: 0.28.14 - '@better-auth/memory-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/memory-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/mongo-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7))': + '@better-auth/mongo-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7))': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 mongodb: 7.1.0(socks@2.8.7) - '@better-auth/prisma-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/prisma-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/telemetry@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))': + '@better-auth/telemetry@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 @@ -7123,6 +7697,25 @@ snapshots: '@esbuild/win32-x64@0.27.4': optional: true + '@fast-csv/format@4.3.5': + dependencies: + '@types/node': 14.18.63 + lodash.escaperegexp: 4.1.2 + lodash.isboolean: 3.0.3 + lodash.isequal: 4.5.0 + lodash.isfunction: 3.0.9 + lodash.isnil: 4.0.0 + + '@fast-csv/parse@4.3.6': + dependencies: + '@types/node': 14.18.63 + lodash.escaperegexp: 4.1.2 + lodash.groupby: 4.6.0 + lodash.isfunction: 3.0.9 + lodash.isnil: 4.0.0 + lodash.isundefined: 3.0.1 + lodash.uniq: 4.5.0 + '@floating-ui/core@1.7.5': dependencies: '@floating-ui/utils': 0.2.11 @@ -7302,6 +7895,23 @@ snapshots: '@js-sdsl/ordered-map@4.4.2': {} + '@kurkle/color@0.3.4': {} + + '@mapbox/node-pre-gyp@1.0.11': + dependencies: + detect-libc: 2.1.2 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.7.4 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + '@mariozechner/clipboard-darwin-arm64@0.3.2': optional: true @@ -8345,18 +8955,119 @@ snapshots: '@radix-ui/rect@1.1.1': {} - '@remirror/core-constants@3.0.0': {} + '@react-pdf/fns@3.1.2': {} - '@rollup/rollup-android-arm-eabi@4.60.0': - optional: true + '@react-pdf/font@4.0.4': + dependencies: + '@react-pdf/pdfkit': 4.1.0 + '@react-pdf/types': 2.9.2 + fontkit: 2.0.4 + is-url: 1.2.4 - '@rollup/rollup-android-arm64@4.60.0': - optional: true + '@react-pdf/image@3.0.4': + dependencies: + '@react-pdf/png-js': 3.0.0 + jay-peg: 1.1.1 - '@rollup/rollup-darwin-arm64@4.60.0': - optional: true + '@react-pdf/layout@4.4.2': + dependencies: + '@react-pdf/fns': 3.1.2 + '@react-pdf/image': 3.0.4 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/stylesheet': 6.1.2 + '@react-pdf/textkit': 6.1.0 + '@react-pdf/types': 2.9.2 + emoji-regex-xs: 1.0.0 + queue: 6.0.2 + yoga-layout: 3.2.1 - '@rollup/rollup-darwin-x64@4.60.0': + '@react-pdf/pdfkit@4.1.0': + dependencies: + '@babel/runtime': 7.29.2 + '@react-pdf/png-js': 3.0.0 + browserify-zlib: 0.2.0 + crypto-js: 4.2.0 + fontkit: 2.0.4 + jay-peg: 1.1.1 + linebreak: 1.1.0 + vite-compatible-readable-stream: 3.6.1 + + '@react-pdf/png-js@3.0.0': + dependencies: + browserify-zlib: 0.2.0 + + '@react-pdf/primitives@4.1.1': {} + + '@react-pdf/reconciler@2.0.0(react@19.2.4)': + dependencies: + object-assign: 4.1.1 + react: 19.2.4 + scheduler: 0.25.0-rc-603e6108-20241029 + + '@react-pdf/render@4.3.2': + dependencies: + '@babel/runtime': 7.29.2 + '@react-pdf/fns': 3.1.2 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/textkit': 6.1.0 + '@react-pdf/types': 2.9.2 + abs-svg-path: 0.1.1 + color-string: 1.9.1 + normalize-svg-path: 1.1.0 + parse-svg-path: 0.1.2 + svg-arc-to-cubic-bezier: 3.2.0 + + '@react-pdf/renderer@4.3.2(react@19.2.4)': + dependencies: + '@babel/runtime': 7.29.2 + '@react-pdf/fns': 3.1.2 + '@react-pdf/font': 4.0.4 + '@react-pdf/layout': 4.4.2 + '@react-pdf/pdfkit': 4.1.0 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/reconciler': 2.0.0(react@19.2.4) + '@react-pdf/render': 4.3.2 + '@react-pdf/types': 2.9.2 + events: 3.3.0 + object-assign: 4.1.1 + prop-types: 15.8.1 + queue: 6.0.2 + react: 19.2.4 + + '@react-pdf/stylesheet@6.1.2': + dependencies: + '@react-pdf/fns': 3.1.2 + '@react-pdf/types': 2.9.2 + color-string: 1.9.1 + hsl-to-hex: 1.0.0 + media-engine: 1.0.3 + postcss-value-parser: 4.2.0 + + '@react-pdf/textkit@6.1.0': + dependencies: + '@react-pdf/fns': 3.1.2 + bidi-js: 1.0.3 + hyphen: 1.14.1 + unicode-properties: 1.4.1 + + '@react-pdf/types@2.9.2': + dependencies: + '@react-pdf/font': 4.0.4 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/stylesheet': 6.1.2 + + '@remirror/core-constants@3.0.0': {} + + '@rollup/rollup-android-arm-eabi@4.60.0': + optional: true + + '@rollup/rollup-android-arm64@4.60.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.0': + optional: true + + '@rollup/rollup-darwin-x64@4.60.0': optional: true '@rollup/rollup-freebsd-arm64@4.60.0': @@ -9387,6 +10098,12 @@ snapshots: '@types/ms@2.1.0': {} + '@types/node@14.18.63': {} + + '@types/node@18.19.130': + dependencies: + undici-types: 5.26.5 + '@types/node@22.19.15': dependencies: undici-types: 6.21.0 @@ -9537,6 +10254,10 @@ snapshots: - debug - supports-color + abbrev@1.1.1: {} + + abs-svg-path@0.1.1: {} + accepts@2.0.0: dependencies: mime-types: 3.0.2 @@ -9544,6 +10265,12 @@ snapshots: acorn@8.16.0: {} + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + agent-base@7.1.4: {} ai@6.0.116(zod@4.3.6): @@ -9575,6 +10302,49 @@ snapshots: any-promise@1.3.0: {} + aproba@2.1.0: {} + + archiver-utils@2.1.0: + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 2.3.8 + + archiver-utils@3.0.4: + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + + archiver@5.3.2: + dependencies: + archiver-utils: 2.1.0 + async: 3.2.6 + buffer-crc32: 0.2.13 + readable-stream: 3.6.2 + readdir-glob: 1.1.3 + tar-stream: 2.2.0 + zip-stream: 4.1.1 + + are-we-there-yet@2.0.0: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + argparse@2.0.1: {} aria-hidden@1.2.6: @@ -9597,6 +10367,8 @@ snapshots: async@3.2.3: {} + async@3.2.6: {} + asynckit@0.4.0: {} aws-ssl-profiles@1.1.2: {} @@ -9619,6 +10391,8 @@ snapshots: balanced-match@4.0.4: {} + base64-js@0.0.8: {} + base64-js@1.5.1: {} baseline-browser-mapping@2.10.8: {} @@ -9632,12 +10406,12 @@ snapshots: better-auth@1.5.5(mongodb@7.1.0(socks@2.8.7))(mysql2@3.20.0(@types/node@22.19.15))(next@16.2.0(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) - '@better-auth/drizzle-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/kysely-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13) - '@better-auth/memory-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/mongo-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7)) - '@better-auth/prisma-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/telemetry': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0)) + '@better-auth/drizzle-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1) + '@better-auth/kysely-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13) + '@better-auth/memory-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1) + '@better-auth/mongo-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7)) + '@better-auth/prisma-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1) + '@better-auth/telemetry': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0)) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 '@noble/ciphers': 2.1.1 @@ -9668,8 +10442,27 @@ snapshots: optionalDependencies: zod: 4.3.6 + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + + big-integer@1.6.52: {} + bignumber.js@9.3.1: {} + binary@0.3.0: + dependencies: + buffers: 0.1.1 + chainsaw: 0.1.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + bluebird@3.4.7: {} + bluebird@3.7.2: {} body-parser@2.2.2: @@ -9688,16 +10481,42 @@ snapshots: bowser@2.14.1: {} + brace-expansion@1.1.13: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.3: + dependencies: + balanced-match: 1.0.2 + brace-expansion@5.0.4: dependencies: balanced-match: 4.0.4 + brotli@1.3.3: + dependencies: + base64-js: 1.5.1 + + browserify-zlib@0.2.0: + dependencies: + pako: 1.0.11 + bson@7.2.0: {} buffer-crc32@0.2.13: {} buffer-equal-constant-time@1.0.1: {} + buffer-indexof-polyfill@1.0.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffers@0.1.1: {} + bytes@3.1.2: {} cac@6.7.14: {} @@ -9716,6 +10535,15 @@ snapshots: caniuse-lite@1.0.30001780: {} + canvas@2.11.2: + dependencies: + '@mapbox/node-pre-gyp': 1.0.11 + nan: 2.26.2 + simple-get: 3.1.1 + transitivePeerDependencies: + - encoding + - supports-color + ccount@2.0.1: {} chai@5.3.3: @@ -9726,6 +10554,10 @@ snapshots: loupe: 3.2.1 pathval: 2.0.1 + chainsaw@0.1.0: + dependencies: + traverse: 0.3.9 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -9741,6 +10573,19 @@ snapshots: character-reference-invalid@2.0.1: {} + chart.js@4.5.1: + dependencies: + '@kurkle/color': 0.3.4 + + chartjs-node-canvas@4.1.6(chart.js@4.5.1): + dependencies: + canvas: 2.11.2 + chart.js: 4.5.1 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + - supports-color + check-error@2.1.3: {} chevrotain-allstar@0.3.1(chevrotain@11.1.2): @@ -9757,6 +10602,8 @@ snapshots: '@chevrotain/utils': 11.1.2 lodash-es: 4.17.23 + chownr@2.0.0: {} + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -9792,6 +10639,8 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clone@2.1.2: {} + clsx@2.1.1: {} cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): @@ -9812,6 +10661,13 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + + color-support@1.1.3: {} + colors@1.0.3: {} combined-stream@1.0.8: @@ -9826,8 +10682,19 @@ snapshots: commander@8.3.0: {} + compress-commons@4.1.2: + dependencies: + buffer-crc32: 0.2.13 + crc32-stream: 4.0.3 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + + concat-map@0.0.1: {} + confbox@0.1.8: {} + console-control-strings@1.1.0: {} + content-disposition@1.0.1: {} content-type@1.0.5: {} @@ -9836,6 +10703,8 @@ snapshots: cookie@0.7.2: {} + core-util-is@1.0.3: {} + cors@2.8.6: dependencies: object-assign: 4.1.1 @@ -9854,6 +10723,13 @@ snapshots: nan: 2.26.2 optional: true + crc-32@1.2.2: {} + + crc32-stream@4.0.3: + dependencies: + crc-32: 1.2.2 + readable-stream: 3.6.2 + crelt@1.0.6: {} cross-spawn@7.0.6: @@ -9862,6 +10738,8 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crypto-js@4.2.0: {} + csstype@3.2.3: {} cycle@1.0.3: {} @@ -10111,6 +10989,10 @@ snapshots: dependencies: character-entities: 2.0.2 + decompress-response@4.2.1: + dependencies: + mimic-response: 2.1.0 + deep-eql@5.0.2: {} deep-extend@0.6.0: {} @@ -10129,6 +11011,8 @@ snapshots: delayed-stream@1.0.0: {} + delegates@1.0.0: {} + denque@2.1.0: {} depd@2.0.0: {} @@ -10143,6 +11027,8 @@ snapshots: dependencies: dequal: 2.0.3 + dfa@1.2.0: {} + diff@8.0.3: {} dom-helpers@5.2.1: @@ -10164,6 +11050,10 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + duplexer2@0.1.4: + dependencies: + readable-stream: 2.3.8 + ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer: 5.2.1 @@ -10182,6 +11072,8 @@ snapshots: embla-carousel@8.6.0: {} + emoji-regex-xs@1.0.0: {} + emoji-regex@8.0.0: {} encodeurl@2.0.0: {} @@ -10285,12 +11177,26 @@ snapshots: eventemitter3@5.0.4: {} + events@3.3.0: {} + eventsource-parser@3.0.6: {} eventsource@3.0.7: dependencies: eventsource-parser: 3.0.6 + exceljs@4.4.0: + dependencies: + archiver: 5.3.2 + dayjs: 1.11.20 + fast-csv: 4.3.6 + jszip: 3.10.1 + readable-stream: 3.6.2 + saxes: 5.0.1 + tmp: 0.2.5 + unzipper: 0.10.14 + uuid: 8.3.2 + execa@9.6.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 @@ -10355,6 +11261,11 @@ snapshots: eyes@0.1.8: {} + fast-csv@4.3.6: + dependencies: + '@fast-csv/format': 4.3.5 + '@fast-csv/parse': 4.3.6 + fast-deep-equal@3.1.3: {} fast-equals@5.4.0: {} @@ -10420,6 +11331,18 @@ snapshots: follow-redirects@1.15.11: {} + fontkit@2.0.4: + dependencies: + '@swc/helpers': 0.5.15 + brotli: 1.3.3 + clone: 2.1.2 + dfa: 1.2.0 + fast-deep-equal: 3.1.3 + restructure: 3.0.2 + tiny-inflate: 1.0.3 + unicode-properties: 1.4.1 + unicode-trie: 2.0.0 + form-data@4.0.5: dependencies: asynckit: 0.4.0 @@ -10445,11 +11368,38 @@ snapshots: fresh@2.0.0: {} + fs-constants@1.0.0: {} + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true + fstream@1.0.12: + dependencies: + graceful-fs: 4.2.11 + inherits: 2.0.4 + mkdirp: 0.5.6 + rimraf: 2.7.1 + function-bind@1.1.2: {} + gauge@3.0.2: + dependencies: + aproba: 2.1.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + gaxios@7.1.4: dependencies: extend: 3.0.2 @@ -10521,6 +11471,15 @@ snapshots: minipass: 7.1.3 path-scurry: 2.0.2 + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + google-auth-library@10.6.2: dependencies: base64-js: 1.5.1 @@ -10548,6 +11507,8 @@ snapshots: dependencies: has-symbols: 1.1.0 + has-unicode@2.0.1: {} + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -10688,6 +11649,12 @@ snapshots: dependencies: lru-cache: 11.2.7 + hsl-to-hex@1.0.0: + dependencies: + hsl-to-rgb-for-reals: 1.1.1 + + hsl-to-rgb-for-reals@1.1.1: {} + html-url-attributes@3.0.1: {} html-void-elements@3.0.0: {} @@ -10707,6 +11674,13 @@ snapshots: transitivePeerDependencies: - supports-color + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 @@ -10714,8 +11688,12 @@ snapshots: transitivePeerDependencies: - supports-color + https@1.0.0: {} + human-signals@8.0.1: {} + hyphen@1.14.1: {} + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -10728,8 +11706,19 @@ snapshots: ignore@7.0.5: {} + image-size@1.2.1: + dependencies: + queue: 6.0.2 + + immediate@3.0.6: {} + inflection@1.13.4: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + inherits@2.0.4: {} ini@1.3.8: {} @@ -10751,6 +11740,8 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 + is-arrayish@0.3.4: {} + is-core-module@2.16.1: dependencies: hasown: 2.0.2 @@ -10775,10 +11766,18 @@ snapshots: is-unicode-supported@2.1.0: {} + is-url@1.2.4: {} + + isarray@1.0.0: {} + isexe@2.0.0: {} isstream@0.1.2: {} + jay-peg@1.1.1: + dependencies: + restructure: 3.0.2 + jiti@2.6.1: {} jose@6.2.2: {} @@ -10815,6 +11814,13 @@ snapshots: ms: 2.1.3 semver: 7.7.4 + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + jwa@2.0.1: dependencies: buffer-equal-constant-time: 1.0.1 @@ -10851,6 +11857,14 @@ snapshots: layout-base@2.0.1: {} + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + + lie@3.3.0: + dependencies: + immediate: 3.0.6 + lightningcss-android-arm64@1.32.0: optional: true @@ -10900,12 +11914,19 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 + linebreak@1.1.0: + dependencies: + base64-js: 0.0.8 + unicode-trie: 2.0.0 + linkify-it@5.0.0: dependencies: uc.micro: 2.1.0 linkifyjs@4.3.2: {} + listenercount@1.0.1: {} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -10916,20 +11937,40 @@ snapshots: lodash.defaults@4.2.0: {} + lodash.difference@4.5.0: {} + + lodash.escaperegexp@4.1.2: {} + + lodash.flatten@4.4.0: {} + + lodash.groupby@4.6.0: {} + lodash.includes@4.3.0: {} lodash.isboolean@3.0.3: {} + lodash.isequal@4.5.0: {} + + lodash.isfunction@3.0.9: {} + lodash.isinteger@4.0.4: {} + lodash.isnil@4.0.0: {} + lodash.isnumber@3.0.3: {} lodash.isplainobject@4.0.6: {} lodash.isstring@4.0.1: {} + lodash.isundefined@3.0.1: {} + lodash.once@4.1.1: {} + lodash.union@4.6.0: {} + + lodash.uniq@4.5.0: {} + lodash@4.17.23: {} long@5.3.2: {} @@ -10960,6 +12001,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + markdown-it@14.1.1: dependencies: argparse: 2.0.1 @@ -11146,6 +12191,8 @@ snapshots: mdurl@2.0.0: {} + media-engine@1.0.3: {} + media-typer@1.1.0: {} memory-pager@1.5.0: {} @@ -11421,18 +12468,41 @@ snapshots: dependencies: mime-db: 1.54.0 + mimic-response@2.1.0: {} + minimatch@10.2.4: dependencies: brace-expansion: 5.0.4 + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.13 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.0.3 + minimist@1.2.8: {} + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + minipass@7.1.3: {} + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + mkdirp@0.5.6: dependencies: minimist: 1.2.8 + mkdirp@1.0.4: {} + mlly@1.8.1: dependencies: acorn: 8.16.0 @@ -11497,8 +12567,7 @@ snapshots: dependencies: lru.min: 1.1.4 - nan@2.26.2: - optional: true + nan@2.26.2: {} nanoid@3.3.11: {} @@ -11543,6 +12612,10 @@ snapshots: node-domexception@1.0.0: {} + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + node-fetch@3.3.2: dependencies: data-uri-to-buffer: 4.0.1 @@ -11551,11 +12624,28 @@ snapshots: node-fs@0.1.7: {} + nopt@5.0.0: + dependencies: + abbrev: 1.1.1 + + normalize-path@3.0.0: {} + + normalize-svg-path@1.1.0: + dependencies: + svg-arc-to-cubic-bezier: 3.2.0 + npm-run-path@6.0.0: dependencies: path-key: 4.0.0 unicorn-magic: 0.3.0 + npmlog@5.0.1: + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -11629,6 +12719,10 @@ snapshots: package-manager-detector@1.6.0: {} + pako@0.2.9: {} + + pako@1.0.11: {} + parse-database-url@0.3.0: dependencies: mongodb-uri: 0.9.7 @@ -11645,6 +12739,8 @@ snapshots: parse-ms@4.0.0: {} + parse-svg-path@0.1.2: {} + parse5-htmlparser2-tree-adapter@6.0.1: dependencies: parse5: 6.0.1 @@ -11667,6 +12763,8 @@ snapshots: path-expression-matcher@1.1.3: {} + path-is-absolute@1.0.1: {} + path-key@3.1.1: {} path-key@4.0.0: {} @@ -11738,6 +12836,8 @@ snapshots: path-data-parser: 0.1.0 points-on-curve: 0.2.0 + postcss-value-parser@4.2.0: {} + postcss@8.4.31: dependencies: nanoid: 3.3.11 @@ -11760,10 +12860,19 @@ snapshots: dependencies: xtend: 4.0.2 + pptxgenjs@3.12.0: + dependencies: + '@types/node': 18.19.130 + https: 1.0.0 + image-size: 1.2.1 + jszip: 3.10.1 + pretty-ms@9.3.0: dependencies: parse-ms: 4.0.0 + process-nextick-args@2.0.1: {} + prompt@1.3.0: dependencies: '@colors/colors': 1.5.0 @@ -11937,6 +13046,10 @@ snapshots: dependencies: side-channel: 1.1.0 + queue@6.0.2: + dependencies: + inherits: 2.0.4 + radix-ui@1.4.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@radix-ui/primitive': 1.1.3 @@ -12092,6 +13205,26 @@ snapshots: dependencies: mute-stream: 0.0.8 + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.9 + recharts-scale@0.4.5: dependencies: decimal.js-light: 2.5.1 @@ -12223,12 +13356,22 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + restructure@3.0.2: {} + retry@0.12.0: {} retry@0.13.1: {} revalidator@0.1.8: {} + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + robust-predicates@3.0.2: {} rollup@4.60.0: @@ -12285,14 +13428,24 @@ snapshots: rw@1.3.3: {} + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safer-buffer@2.1.2: {} + saxes@5.0.1: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.25.0-rc-603e6108-20241029: {} + scheduler@0.27.0: {} semver@5.7.2: {} + semver@6.3.1: {} + semver@7.7.4: {} send@1.2.1: @@ -12324,6 +13477,8 @@ snapshots: set-cookie-parser@3.0.1: {} + setimmediate@1.0.5: {} + setprototypeof@1.2.0: {} sharp@0.34.5: @@ -12409,6 +13564,18 @@ snapshots: signal-exit@4.1.0: {} + simple-concat@1.0.1: {} + + simple-get@3.1.1: + dependencies: + decompress-response: 4.2.1 + once: 1.4.0 + simple-concat: 1.0.1 + + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + sisteransi@1.0.5: {} smart-buffer@4.2.0: {} @@ -12500,6 +13667,14 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + stringify-entities@4.0.4: dependencies: character-entities-html4: 2.1.0 @@ -12548,12 +13723,31 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svg-arc-to-cubic-bezier@3.2.0: {} + tailwind-merge@3.5.0: {} tailwindcss@4.2.2: {} tapable@2.3.0: {} + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -12562,6 +13756,8 @@ snapshots: dependencies: any-promise: 1.3.0 + tiny-inflate@1.0.3: {} + tiny-invariant@1.3.3: {} tinybench@2.9.0: {} @@ -12581,6 +13777,8 @@ snapshots: tinyspy@4.0.4: {} + tmp@0.2.5: {} + toidentifier@1.0.1: {} token-types@6.1.2: @@ -12596,10 +13794,14 @@ snapshots: '@tokenlens/helpers': 1.3.1 '@tokenlens/models': 1.3.0 + tr46@0.0.3: {} + tr46@5.1.1: dependencies: punycode: 2.3.1 + traverse@0.3.9: {} + trim-lines@3.0.1: {} trough@2.2.0: {} @@ -12658,10 +13860,22 @@ snapshots: uint8array-extras@1.5.0: {} + undici-types@5.26.5: {} + undici-types@6.21.0: {} undici@7.24.4: {} + unicode-properties@1.4.1: + dependencies: + base64-js: 1.5.1 + unicode-trie: 2.0.0 + + unicode-trie@2.0.0: + dependencies: + pako: 0.2.9 + tiny-inflate: 1.0.3 + unicorn-magic@0.3.0: {} unified@11.0.5: @@ -12709,6 +13923,19 @@ snapshots: unpipe@1.0.0: {} + unzipper@0.10.14: + dependencies: + big-integer: 1.6.52 + binary: 0.3.0 + bluebird: 3.4.7 + buffer-indexof-polyfill: 1.0.2 + duplexer2: 0.1.4 + fstream: 1.0.12 + graceful-fs: 4.2.11 + listenercount: 1.0.1 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.4): dependencies: react: 19.2.4 @@ -12736,10 +13963,14 @@ snapshots: dependencies: react: 19.2.4 + util-deprecate@1.0.2: {} + uuid@11.1.0: {} uuid@13.0.0: {} + uuid@8.3.2: {} + vary@1.1.2: {} vaul@1.1.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): @@ -12783,6 +14014,12 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 + vite-compatible-readable-stream@3.6.1: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + vite-node@3.2.4(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: cac: 6.7.14 @@ -12885,6 +14122,8 @@ snapshots: web-streams-polyfill@3.3.3: {} + webidl-conversions@3.0.1: {} + webidl-conversions@7.0.0: {} whatwg-url@14.2.0: @@ -12892,6 +14131,11 @@ snapshots: tr46: 5.1.1 webidl-conversions: 7.0.0 + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + when@2.0.1: {} which-module@2.0.1: {} @@ -12905,6 +14149,10 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + winston@2.4.7: dependencies: async: 2.6.4 @@ -12930,12 +14178,16 @@ snapshots: ws@8.19.0: {} + xmlchars@2.2.0: {} + xtend@4.0.2: {} y18n@4.0.3: {} y18n@5.0.8: {} + yallist@4.0.0: {} + yaml@2.8.2: {} yargs-parser@18.1.3: @@ -12988,6 +14240,14 @@ snapshots: yoctocolors@2.1.2: {} + yoga-layout@3.2.1: {} + + zip-stream@4.1.1: + dependencies: + archiver-utils: 3.0.4 + compress-commons: 4.1.2 + readable-stream: 3.6.2 + zod-to-json-schema@3.25.1(zod@4.3.6): dependencies: zod: 4.3.6 From e64e32cd5e25ae0e0c522f5c58b4373e41e9afb3 Mon Sep 17 00:00:00 2001 From: shanvit Date: Wed, 1 Apr 2026 13:25:42 +0530 Subject: [PATCH 03/12] feat(skill-reports): implement tool definitions and package index - createReportListTemplatesTool: lists registered templates as JSON - createReportGenerateTool: validates data against TypeBox schema, enforces 20-chart limit, renders via template.render(), writes to /workspace/output/ - createReportExecuteCodeTool: installs deps, runs Python/JS code in sandbox, collects output files from /workspace/output/ - src/index.ts: re-exports tools and types - templates/types.ts, templates/registry.ts: stubs for renderers task (task 1) --- packages/skills/reports/package.json | 11 +- packages/skills/reports/src/index.ts | 6 +- .../skills/reports/src/templates/registry.ts | 71 ++++++ .../skills/reports/src/templates/types.ts | 61 +++++ packages/skills/reports/src/tools.test.ts | 96 ++++++++ packages/skills/reports/src/tools.ts | 233 ++++++++++++++++++ 6 files changed, 473 insertions(+), 5 deletions(-) create mode 100644 packages/skills/reports/src/templates/registry.ts create mode 100644 packages/skills/reports/src/templates/types.ts create mode 100644 packages/skills/reports/src/tools.test.ts create mode 100644 packages/skills/reports/src/tools.ts diff --git a/packages/skills/reports/package.json b/packages/skills/reports/package.json index d4c1c62..4eaf238 100644 --- a/packages/skills/reports/package.json +++ b/packages/skills/reports/package.json @@ -13,10 +13,17 @@ }, "scripts": { "build": "tsc", - "check": "tsc --noEmit" + "check": "tsc --noEmit", + "test": "vitest --run" + }, + "dependencies": { + "@mariozechner/pi-agent-core": "^0.61.0", + "@mariozechner/pi-coding-agent": "^0.61.0", + "@sinclair/typebox": "^0.34.48" }, "devDependencies": { "@types/node": "^22.15.2", - "typescript": "^5.7.3" + "typescript": "^5.7.3", + "vitest": "^3.1.1" } } diff --git a/packages/skills/reports/src/index.ts b/packages/skills/reports/src/index.ts index 755e155..70e12cc 100644 --- a/packages/skills/reports/src/index.ts +++ b/packages/skills/reports/src/index.ts @@ -1,3 +1,3 @@ -// Reports Skill - Template-based and agent-generated report creation. -// Implementation in Phase 6. -export {} +// Reports Skill — template-based and agent-generated report creation. +export { createReportListTemplatesTool, createReportGenerateTool, createReportExecuteCodeTool } from "./tools.js" +export type { ReportTemplate, MonthlyReportData, RenderOpts } from "./templates/types.js" diff --git a/packages/skills/reports/src/templates/registry.ts b/packages/skills/reports/src/templates/registry.ts new file mode 100644 index 0000000..6d3d8d4 --- /dev/null +++ b/packages/skills/reports/src/templates/registry.ts @@ -0,0 +1,71 @@ +/** + * Template registry for the report generation skill. + * Renderers task (task 1) provides concrete template implementations. + * This stub registers built-in templates and provides lookup helpers. + */ + +import { Type } from "@sinclair/typebox" +import type { MonthlyReportData, RenderOpts, ReportFormat, ReportTemplate } from "./types.js" + +/** Built-in monthly report template. */ +const monthlyReportTemplate: ReportTemplate = { + name: "monthly-report", + label: "Monthly Report", + description: "A structured monthly report with summary metrics, charts, and tables.", + schema: Type.Object({ + title: Type.String(), + period: Type.Object({ from: Type.String(), to: Type.String() }), + summary: Type.Array( + Type.Object({ + metric: Type.String(), + value: Type.Number(), + change: Type.Number(), + }), + ), + charts: Type.Array( + Type.Object({ + type: Type.Union([Type.Literal("bar"), Type.Literal("line"), Type.Literal("pie")]), + title: Type.String(), + data: Type.Array(Type.Object({ label: Type.String(), value: Type.Number() })), + }), + ), + tables: Type.Array( + Type.Object({ + title: Type.String(), + headers: Type.Array(Type.String()), + rows: Type.Array(Type.Array(Type.Union([Type.String(), Type.Number()]))), + }), + ), + }), + formats: ["pdf", "pptx", "csv", "xlsx", "png", "svg"], + render: async (_format: ReportFormat, _data: MonthlyReportData, _opts: RenderOpts): Promise => { + // Stub: concrete implementation provided by the renderers task. + return Buffer.from(JSON.stringify({ stub: true })) + }, +} + +const registry = new Map([[monthlyReportTemplate.name, monthlyReportTemplate]]) + +/** + * List all registered report templates. + * + * @returns Array of all registered templates. + */ +export const listTemplates = (): ReportTemplate[] => Array.from(registry.values()) + +/** + * Look up a template by name. + * + * @param name - Template identifier. + * @returns The template, or undefined if not found. + */ +export const getTemplate = (name: string): ReportTemplate | undefined => registry.get(name) + +/** + * Register a custom report template. + * + * @param template - Template to register. + */ +export const registerTemplate = (template: ReportTemplate): void => { + registry.set(template.name, template) +} diff --git a/packages/skills/reports/src/templates/types.ts b/packages/skills/reports/src/templates/types.ts new file mode 100644 index 0000000..8f0c326 --- /dev/null +++ b/packages/skills/reports/src/templates/types.ts @@ -0,0 +1,61 @@ +/** + * Types for the report generation skill. + * Renderers task (task 1) provides concrete implementations. + */ +import type { TSchema } from "@sinclair/typebox" +export type { TSchema } + +/** Output format supported by report templates. */ +export type ReportFormat = "pdf" | "pptx" | "csv" | "xlsx" | "png" | "svg" + +/** Options passed to a template renderer. */ +export interface RenderOpts { + /** Directory where the rendered file should be written. */ + outputDir: string +} + +/** A single chart definition within a report. */ +export interface ChartDefinition { + type: "bar" | "line" | "pie" + title: string + data: { label: string; value: number }[] +} + +/** A single table definition within a report. */ +export interface TableDefinition { + title: string + headers: string[] + rows: (string | number)[][] +} + +/** Data schema for the built-in monthly report template. */ +export interface MonthlyReportData { + title: string + period: { from: string; to: string } + summary: { metric: string; value: number; change: number }[] + charts: ChartDefinition[] + tables: TableDefinition[] +} + +/** A report template definition. */ +export interface ReportTemplate { + /** Unique template identifier, e.g. "monthly-report". */ + name: string + /** Human-readable display name. */ + label: string + /** Short description of what the template produces. */ + description: string + /** TypeBox schema for the data payload. */ + schema: TSchema + /** Supported output formats for this template. */ + formats: ReportFormat[] + /** + * Render the template to a Buffer. + * + * @param format - Output format. + * @param data - Template data matching the schema. + * @param opts - Render options. + * @returns Buffer containing the rendered output. + */ + render: (format: ReportFormat, data: MonthlyReportData, opts: RenderOpts) => Promise +} diff --git a/packages/skills/reports/src/tools.test.ts b/packages/skills/reports/src/tools.test.ts new file mode 100644 index 0000000..5489fdc --- /dev/null +++ b/packages/skills/reports/src/tools.test.ts @@ -0,0 +1,96 @@ +import type { ExtensionContext } from "@mariozechner/pi-coding-agent" +import type { Type } from "@sinclair/typebox" +import { describe, expect, it } from "vitest" +import { createReportExecuteCodeTool, createReportGenerateTool, createReportListTemplatesTool } from "./tools.js" + +// ─── Helpers ───────────────────────────────────────────────────────────────── + +// Minimal stub — tests don't rely on ctx methods. +const stubCtx = {} as ExtensionContext + +const invoke = async (tool: ReturnType, params: unknown) => { + const result = await tool.execute("test-call-id", params, new AbortController().signal, () => {}, stubCtx) + return result.content[0].type === "text" ? (result.content[0] as { type: "text"; text: string }).text : "" +} + +// ─── report_list_templates ──────────────────────────────────────────────────── + +describe("report_list_templates", () => { + it("returns an array that includes the monthly-report template", async () => { + const tool = createReportListTemplatesTool() + const output = await invoke(tool, {}) + const templates = JSON.parse(output) as { name: string }[] + expect(Array.isArray(templates)).toBe(true) + const names = templates.map((t) => t.name) + expect(names).toContain("monthly-report") + }) +}) + +// ─── report_generate ───────────────────────────────────────────────────────── + +describe("report_generate", () => { + it("returns an error for an unknown template name", async () => { + const tool = createReportGenerateTool() + const output = await invoke(tool, { + template: "does-not-exist", + format: "pdf", + data: {}, + }) + expect(output).toContain("Unknown template: does-not-exist") + }) + + it("returns an error when charts array exceeds 20 entries", async () => { + const tool = createReportGenerateTool() + const charts = Array.from({ length: 21 }, (_, i) => ({ + type: "bar" as const, + title: `Chart ${i}`, + data: [{ label: "A", value: i }], + })) + const output = await invoke(tool, { + template: "monthly-report", + format: "pdf", + data: { + title: "Test", + period: { from: "2025-01-01", to: "2025-01-31" }, + summary: [], + charts, + tables: [], + }, + }) + expect(output).toContain("Chart limit exceeded") + expect(output).toContain("21") + }) + + it("returns a schema validation error for missing required field", async () => { + const tool = createReportGenerateTool() + // 'title' is required by the monthly-report schema but omitted here + const output = await invoke(tool, { + template: "monthly-report", + format: "pdf", + data: { + period: { from: "2025-01-01", to: "2025-01-31" }, + summary: [], + charts: [], + tables: [], + }, + }) + expect(output).toContain("Validation errors") + }) +}) + +// ─── report_execute_code ────────────────────────────────────────────────────── + +describe("report_execute_code", () => { + it("has the expected parameter shape", () => { + const tool = createReportExecuteCodeTool() + expect(tool.name).toBe("report_execute_code") + + const paramSchema = tool.parameters as ReturnType + const props = paramSchema.properties as Record + + expect(props).toHaveProperty("language") + expect(props).toHaveProperty("code") + expect(props).toHaveProperty("dependencies") + expect(props).toHaveProperty("outputDir") + }) +}) diff --git a/packages/skills/reports/src/tools.ts b/packages/skills/reports/src/tools.ts new file mode 100644 index 0000000..b33996f --- /dev/null +++ b/packages/skills/reports/src/tools.ts @@ -0,0 +1,233 @@ +import { execFileSync } from "node:child_process" +import { randomUUID } from "node:crypto" +import { mkdirSync, readdirSync, statSync, writeFileSync } from "node:fs" +import type { AgentToolResult } from "@mariozechner/pi-agent-core" +import type { ToolDefinition } from "@mariozechner/pi-coding-agent" +import { Type } from "@sinclair/typebox" +import type { TSchema } from "@sinclair/typebox" +import { Value } from "@sinclair/typebox/value" +import { getTemplate, listTemplates } from "./templates/registry.js" +import type { MonthlyReportData } from "./templates/types.js" + +// ─── Helpers ───────────────────────────────────────────────────────────────── + +const textResult = (text: string): AgentToolResult => ({ + content: [{ type: "text", text }], + details: {}, +}) + +const OUTPUT_DIR = "/workspace/output" + +const MIME_MAP: Record = { + png: "image/png", + svg: "image/svg+xml", + pdf: "application/pdf", + pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation", + csv: "text/csv", + xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", +} + +const OUTPUT_EXTENSIONS = new Set(["png", "svg", "pdf", "pptx", "csv", "xlsx"]) + +// ─── Tool factories ─────────────────────────────────────────────────────────── + +/** + * Create the report_list_templates tool. + * + * Returns a JSON array of all registered report templates, including their + * name, label, description, and supported output formats. + */ +export const createReportListTemplatesTool = (): ToolDefinition => ({ + name: "report_list_templates", + label: "List Report Templates", + description: "List all available report templates with their names, descriptions, and supported formats.", + promptSnippet: "report_list_templates() — list available report templates", + parameters: Type.Object({}), + execute: async (_toolCallId, _params, _signal, _onUpdate, _ctx): Promise> => { + const templates = listTemplates().map((t) => ({ + name: t.name, + label: t.label, + description: t.description, + formats: t.formats, + })) + return textResult(JSON.stringify(templates, null, 2)) + }, +}) + +/** + * Create the report_generate tool. + * + * Validates the input data against the template's TypeBox schema, renders + * the report, writes it to /workspace/output/, and returns the file path + * and size. + */ +export const createReportGenerateTool = (): ToolDefinition => ({ + name: "report_generate", + label: "Generate Report", + description: + "Generate a report from a registered template and structured data. " + + "Returns the file path and size of the generated report.", + promptSnippet: "report_generate(template, format, data) — render a report from a template", + parameters: Type.Object({ + template: Type.String({ description: "Template name, e.g. 'monthly-report'." }), + format: Type.Union( + [ + Type.Literal("pdf"), + Type.Literal("pptx"), + Type.Literal("csv"), + Type.Literal("xlsx"), + Type.Literal("png"), + Type.Literal("svg"), + ], + { description: "Output format." }, + ), + data: Type.Object( + {}, + { + additionalProperties: true, + description: "Structured data matching the template schema.", + }, + ), + outputFilename: Type.Optional(Type.String({ description: "Override the output filename." })), + }), + execute: async (_toolCallId, params, _signal, _onUpdate, _ctx): Promise> => { + const p = params as { + template: string + format: "pdf" | "pptx" | "csv" | "xlsx" | "png" | "svg" + data: Record + outputFilename?: string + } + + const template = getTemplate(p.template) + if (!template) { + return textResult(`Unknown template: ${p.template}`) + } + + // Schema validation + if (!Value.Check(template.schema as TSchema, p.data)) { + const errors = [...Value.Errors(template.schema as TSchema, p.data)] + const lines = errors.map((e) => ` - ${e.path || "/"}: ${e.message}`) + return textResult(`Validation errors:\n${lines.join("\n")}`) + } + + // Chart limit guard + const charts = (p.data as { charts?: unknown[] }).charts + if (Array.isArray(charts) && charts.length > 20) { + return textResult( + `Chart limit exceeded: maximum 20 charts per report. You provided ${charts.length}. Split into multiple reports or reduce the number of charts.`, + ) + } + + mkdirSync(OUTPUT_DIR, { recursive: true }) + + const buffer = await template.render(p.format, p.data as unknown as MonthlyReportData, { outputDir: OUTPUT_DIR }) + + const filename = p.outputFilename ?? `${p.template}-${Date.now()}.${p.format}` + const outPath = `${OUTPUT_DIR}/${filename}` + writeFileSync(outPath, buffer) + + const sizeBytes = statSync(outPath).size + + return textResult(JSON.stringify({ path: outPath, filename, sizeBytes }, null, 2)) + }, +}) + +/** + * Create the report_execute_code tool. + * + * Installs optional dependencies, writes code to a temp file, executes it + * inside /workspace, and returns paths to any generated output files together + * with captured stdout. + */ +export const createReportExecuteCodeTool = (): ToolDefinition => ({ + name: "report_execute_code", + label: "Execute Report Code", + description: + "Execute Python or JavaScript code to generate charts, reports, or data visualizations. " + + "Code should save output files to /workspace/output/. " + + "Returns file paths and stdout.", + promptSnippet: + "report_execute_code(language, code, dependencies?, outputDir?) — run code that generates report files", + parameters: Type.Object({ + language: Type.Union([Type.Literal("python"), Type.Literal("javascript")], { + description: "Runtime to use.", + }), + code: Type.String({ description: "Code to execute." }), + dependencies: Type.Optional( + Type.Array(Type.String(), { description: "Additional packages to install before execution." }), + ), + outputDir: Type.Optional( + Type.String({ description: "Override the output directory (default: /workspace/output)." }), + ), + }), + execute: async (_toolCallId, params, _signal, _onUpdate, _ctx): Promise> => { + const p = params as { + language: "python" | "javascript" + code: string + dependencies?: string[] + outputDir?: string + } + + const outputDir = p.outputDir ?? OUTPUT_DIR + mkdirSync(outputDir, { recursive: true }) + + // Install dependencies + if (p.dependencies && p.dependencies.length > 0) { + try { + if (p.language === "python") { + execFileSync("pip3", ["install", "--break-system-packages", ...p.dependencies], { + timeout: 30000, + }) + } else { + execFileSync("npm", ["install", "-g", ...p.dependencies], { + timeout: 30000, + }) + } + } catch (err) { + const msg = err instanceof Error ? err.message : String(err) + return textResult(`Dependency installation failed: ${msg}`) + } + } + + // Write code to temp file + const ext = p.language === "python" ? "py" : "js" + mkdirSync("/tmp/agent", { recursive: true }) + const scriptPath = `/tmp/agent/report_${randomUUID()}.${ext}` + writeFileSync(scriptPath, p.code) + + // Execute + let stdout = "" + try { + const runtime = p.language === "python" ? "python3" : "node" + const result = execFileSync(runtime, [scriptPath], { + timeout: 60000, + cwd: "/workspace", + encoding: "utf-8", + }) + stdout = result + } catch (err) { + const execErr = err as NodeJS.ErrnoException & { stderr?: string } + const msg = execErr.stderr ?? execErr.message ?? String(err) + return textResult(msg) + } + + // Collect output files + const files = readdirSync(outputDir) + .filter((f) => { + const ext = f.split(".").pop() ?? "" + return OUTPUT_EXTENSIONS.has(ext) + }) + .map((filename) => { + const filePath = `${outputDir}/${filename}` + const ext = filename.split(".").pop() ?? "" + return { + path: filePath, + filename, + sizeBytes: statSync(filePath).size, + mimeType: MIME_MAP[ext] ?? "application/octet-stream", + } + }) + + return textResult(JSON.stringify({ files, stdout }, null, 2)) + }, +}) From cba6253609e57359dd101af6addded0f0b261f79 Mon Sep 17 00:00:00 2001 From: shanvit Date: Wed, 1 Apr 2026 13:30:33 +0530 Subject: [PATCH 04/12] feat(agents): wire report tools from skill-reports into createDefaultTools --- packages/agents/package.json | 1 + packages/agents/src/pi/tools.ts | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/agents/package.json b/packages/agents/package.json index bd1add9..655066b 100644 --- a/packages/agents/package.json +++ b/packages/agents/package.json @@ -29,6 +29,7 @@ "uuid": "^13.0.0", "@openzosma/db": "workspace:*", "@openzosma/integrations": "workspace:*", + "@openzosma/skill-reports": "workspace:*", "pg": "^8.13.1", "@mariozechner/pi-agent-core": "^0.61.0" }, diff --git a/packages/agents/src/pi/tools.ts b/packages/agents/src/pi/tools.ts index 5f6c960..692e1ff 100644 --- a/packages/agents/src/pi/tools.ts +++ b/packages/agents/src/pi/tools.ts @@ -12,10 +12,25 @@ import type { ToolDefinition } from "@mariozechner/pi-coding-agent" import { integrationQueries } from "@openzosma/db" import type { IntegrationConfig } from "@openzosma/db" import { executequery, getschema, safeDecrypt } from "@openzosma/integrations" +import { + createReportExecuteCodeTool, + createReportGenerateTool, + createReportListTemplatesTool, +} from "@openzosma/skill-reports" import { Type } from "@sinclair/typebox" import type pg from "pg" -export type BuiltInToolName = "read" | "bash" | "edit" | "write" | "grep" | "find" | "ls" +export type BuiltInToolName = + | "read" + | "bash" + | "edit" + | "write" + | "grep" + | "find" + | "ls" + | "report_list_templates" + | "report_generate" + | "report_execute_code" export const createDefaultTools = (workspaceDir: string, toolsEnabled?: string[]) => { const allTools = [ @@ -26,6 +41,9 @@ export const createDefaultTools = (workspaceDir: string, toolsEnabled?: string[] { name: "grep", tool: createGrepTool(workspaceDir) }, { name: "find", tool: createFindTool(workspaceDir) }, { name: "ls", tool: createLsTool(workspaceDir) }, + { name: "report_list_templates", tool: createReportListTemplatesTool() }, + { name: "report_generate", tool: createReportGenerateTool() }, + { name: "report_execute_code", tool: createReportExecuteCodeTool() }, ] as const if (!toolsEnabled || toolsEnabled.length === 0) { From 9104da32c7cc75a933af8bdea99e7a3fec71e5a6 Mon Sep 17 00:00:00 2001 From: shanvit Date: Wed, 1 Apr 2026 13:39:31 +0530 Subject: [PATCH 05/12] feat(dockerfile): add native canvas libs, Python report deps, /workspace/output dir --- infra/openshell/Dockerfile | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/infra/openshell/Dockerfile b/infra/openshell/Dockerfile index 8de6e9e..cb5ac83 100644 --- a/infra/openshell/Dockerfile +++ b/infra/openshell/Dockerfile @@ -65,23 +65,40 @@ FROM node:22-slim # make + g++ are required for native npm modules that use node-gyp. # Node.js and npm are already present from the node:22-slim base image. RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + curl \ + g++ \ git \ + iproute2 \ + jq \ + less \ + libcairo2-dev \ + libgif-dev \ + libjpeg-dev \ + libpango1.0-dev \ + librsvg2-dev \ + make \ + pkg-config \ python3 \ python3-pip \ python3-venv \ tini \ - curl \ - iproute2 \ tree \ - jq \ - wget \ - less \ unzip \ + wget \ zip \ - make \ - g++ \ && rm -rf /var/lib/apt/lists/* +# Install Python reporting libraries +RUN pip3 install --break-system-packages \ + matplotlib \ + numpy \ + openpyxl \ + pandas \ + python-pptx \ + reportlab \ + seaborn + # Create sandbox user (OpenShell convention: non-root execution) # --home is required so homedir() returns a real path; bootstrapPiExtensions() # writes config files to ~/.pi/ and will crash if home is /nonexistent. @@ -123,7 +140,7 @@ RUN chown root:root -R ./skills/ && chmod 444 -R ./skills/ # In per-user persistent sandboxes, this directory persists across sessions. # /sandbox is the OpenShell writable root where .env is uploaded. # .knowledge-base is pre-created so the agent prompt doesn't error on ls. -RUN mkdir -p /workspace/.knowledge-base /tmp/agent /sandbox && \ +RUN mkdir -p /workspace/.knowledge-base /workspace/output /tmp/agent /sandbox && \ chown -R sandbox:sandbox /workspace /tmp/agent /sandbox # Copy entrypoint into /app/ which is already in the policy read_only allowlist. From 536292039b440beebf3b41109f19d5841499dcda Mon Sep 17 00:00:00 2001 From: shanvit Date: Wed, 1 Apr 2026 13:42:39 +0530 Subject: [PATCH 06/12] fix(agents): wire report tools as customTools, split ToolDefinition from AgentTool --- packages/agents/src/pi.agent.ts | 10 +++--- packages/agents/src/pi/tools.ts | 55 ++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/packages/agents/src/pi.agent.ts b/packages/agents/src/pi.agent.ts index dca2810..f2c3e1e 100644 --- a/packages/agents/src/pi.agent.ts +++ b/packages/agents/src/pi.agent.ts @@ -11,7 +11,7 @@ import { createLogger } from "@openzosma/logger" import { bootstrapMemory } from "@openzosma/memory" import { DEFAULT_SYSTEM_PROMPT } from "./pi/config.js" import { resolveModel } from "./pi/model.js" -import { createDefaultTools, createListDatabaseSchemasTool, createQueryDatabaseTool } from "./pi/tools.js" +import { createDefaultTools, createListDatabaseSchemasTool, createQueryDatabaseTool, createReportTools } from "./pi/tools.js" import type { AgentMessage, AgentProvider, AgentSession, AgentSessionOpts, AgentStreamEvent } from "./types.js" const log = createLogger({ component: "agents" }) @@ -52,9 +52,11 @@ class PiAgentSession implements AgentSession { memoryDir: opts.memoryDir, }) const toolList = [...createDefaultTools(opts.workspaceDir, opts.toolsEnabled)] - const customTools = opts.dbPool - ? [createQueryDatabaseTool(opts.dbPool), createListDatabaseSchemasTool(opts.dbPool)] - : undefined + const reportTools = createReportTools(opts.toolsEnabled) + const customTools = [ + ...reportTools, + ...(opts.dbPool ? [createQueryDatabaseTool(opts.dbPool), createListDatabaseSchemasTool(opts.dbPool)] : []), + ] const { model, apiKey } = resolveModel({ provider: opts.provider, model: opts.model, diff --git a/packages/agents/src/pi/tools.ts b/packages/agents/src/pi/tools.ts index 692e1ff..29dc249 100644 --- a/packages/agents/src/pi/tools.ts +++ b/packages/agents/src/pi/tools.ts @@ -32,19 +32,52 @@ export type BuiltInToolName = | "report_generate" | "report_execute_code" +// Built-in AgentTool entries (accepted by createAgentSession's `tools` field). +const BUILTIN_TOOL_NAMES = ["read", "bash", "edit", "write", "grep", "find", "ls"] as const +type BuiltinToolName = (typeof BUILTIN_TOOL_NAMES)[number] + +// Custom ToolDefinition entries (accepted by createAgentSession's `customTools` field). +const CUSTOM_TOOL_NAMES = ["report_list_templates", "report_generate", "report_execute_code"] as const +type CustomToolName = (typeof CUSTOM_TOOL_NAMES)[number] + +/** + * Create the built-in AgentTool instances (read, bash, edit, write, grep, find, ls). + * These go in `tools` when calling createAgentSession. + * + * @param workspaceDir - Root workspace directory. + * @param toolsEnabled - Optional allow-list of tool names. If omitted, all tools are returned. + */ export const createDefaultTools = (workspaceDir: string, toolsEnabled?: string[]) => { const allTools = [ - { name: "read", tool: createReadTool(workspaceDir) }, - { name: "bash", tool: createBashTool(workspaceDir) }, - { name: "edit", tool: createEditTool(workspaceDir) }, - { name: "write", tool: createWriteTool(workspaceDir) }, - { name: "grep", tool: createGrepTool(workspaceDir) }, - { name: "find", tool: createFindTool(workspaceDir) }, - { name: "ls", tool: createLsTool(workspaceDir) }, - { name: "report_list_templates", tool: createReportListTemplatesTool() }, - { name: "report_generate", tool: createReportGenerateTool() }, - { name: "report_execute_code", tool: createReportExecuteCodeTool() }, - ] as const + { name: "read" as BuiltinToolName, tool: createReadTool(workspaceDir) }, + { name: "bash" as BuiltinToolName, tool: createBashTool(workspaceDir) }, + { name: "edit" as BuiltinToolName, tool: createEditTool(workspaceDir) }, + { name: "write" as BuiltinToolName, tool: createWriteTool(workspaceDir) }, + { name: "grep" as BuiltinToolName, tool: createGrepTool(workspaceDir) }, + { name: "find" as BuiltinToolName, tool: createFindTool(workspaceDir) }, + { name: "ls" as BuiltinToolName, tool: createLsTool(workspaceDir) }, + ] + + if (!toolsEnabled || toolsEnabled.length === 0) { + return allTools.map((t) => t.tool) + } + + const allow = new Set(toolsEnabled) + return allTools.filter((t) => allow.has(t.name)).map((t) => t.tool) +} + +/** + * Create the report ToolDefinition instances (report_list_templates, report_generate, report_execute_code). + * These go in `customTools` when calling createAgentSession. + * + * @param toolsEnabled - Optional allow-list of tool names. If omitted, all report tools are returned. + */ +export const createReportTools = (toolsEnabled?: string[]): ToolDefinition[] => { + const allTools = [ + { name: "report_list_templates" as CustomToolName, tool: createReportListTemplatesTool() }, + { name: "report_generate" as CustomToolName, tool: createReportGenerateTool() }, + { name: "report_execute_code" as CustomToolName, tool: createReportExecuteCodeTool() }, + ] if (!toolsEnabled || toolsEnabled.length === 0) { return allTools.map((t) => t.tool) From 2ef10002fb380e170d2e6fdd2d81f95fa2f7e523 Mon Sep 17 00:00:00 2001 From: shanvit Date: Wed, 1 Apr 2026 13:44:49 +0530 Subject: [PATCH 07/12] chore: package changes --- pnpm-lock.yaml | 50 +++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bbd07db..ec61707 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -372,6 +372,9 @@ importers: '@openzosma/memory': specifier: workspace:* version: link:../memory + '@openzosma/skill-reports': + specifier: workspace:* + version: link:../skills/reports '@sinclair/typebox': specifier: ^0.34.48 version: 0.34.48 @@ -673,11 +676,17 @@ importers: packages/skills/reports: dependencies: + '@mariozechner/pi-agent-core': + specifier: ^0.61.0 + version: 0.61.1(ws@8.19.0)(zod@4.3.6) + '@mariozechner/pi-coding-agent': + specifier: ^0.61.0 + version: 0.61.0(ws@8.19.0)(zod@4.3.6) '@react-pdf/renderer': specifier: ^4.3.0 version: 4.3.2(react@19.2.4) '@sinclair/typebox': - specifier: ^0.34.9 + specifier: ^0.34.48 version: 0.34.48 chart.js: specifier: ^4.4.9 @@ -704,6 +713,9 @@ importers: typescript: specifier: ^5.7.3 version: 5.9.3 + vitest: + specifier: ^3.1.1 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2) packages: @@ -7486,14 +7498,14 @@ snapshots: nanostores: 1.2.0 zod: 4.3.6 - '@better-auth/drizzle-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/drizzle-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/kysely-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13)': + '@better-auth/kysely-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 kysely: 0.28.13 @@ -7503,25 +7515,25 @@ snapshots: '@better-auth/utils': 0.3.1 kysely: 0.28.14 - '@better-auth/memory-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/memory-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/mongo-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7))': + '@better-auth/mongo-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7))': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 mongodb: 7.1.0(socks@2.8.7) - '@better-auth/prisma-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/prisma-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/telemetry@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))': + '@better-auth/telemetry@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))': dependencies: - '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 @@ -10406,12 +10418,12 @@ snapshots: better-auth@1.5.5(mongodb@7.1.0(socks@2.8.7))(mysql2@3.20.0(@types/node@22.19.15))(next@16.2.0(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0) - '@better-auth/drizzle-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/kysely-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13) - '@better-auth/memory-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/mongo-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7)) - '@better-auth/prisma-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/telemetry': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0)) + '@better-auth/drizzle-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1) + '@better-auth/kysely-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.13) + '@better-auth/memory-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1) + '@better-auth/mongo-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7)) + '@better-auth/prisma-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0))(@better-auth/utils@0.3.1) + '@better-auth/telemetry': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.13)(nanostores@1.2.0)) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 '@noble/ciphers': 2.1.1 From a4cf7caa04ae00654075133706808180ae136106 Mon Sep 17 00:00:00 2001 From: shanvit Date: Wed, 1 Apr 2026 13:54:56 +0530 Subject: [PATCH 08/12] feat(dockerfile): globally install chart.js, chartjs-node-canvas, d3, exceljs for agent code reports --- docs/CURRENT-TASK.md | 84 ++++++++++++++++++++++++++++++++++++++ infra/openshell/Dockerfile | 3 ++ 2 files changed, 87 insertions(+) create mode 100644 docs/CURRENT-TASK.md diff --git a/docs/CURRENT-TASK.md b/docs/CURRENT-TASK.md new file mode 100644 index 0000000..0f84044 --- /dev/null +++ b/docs/CURRENT-TASK.md @@ -0,0 +1,84 @@ +Description +Implement the report generation skill at packages/skills/reports/ (currently an empty placeholder: export {}). This skill enables agents to produce formatted deliverables -- PDF reports, PPTX presentations, charts, and data exports. + +Two approaches are supported simultaneously: + +A) Template-based reports +Agent produces structured JSON matching a predefined template schema. The skill renders it into the requested format. + + +Implement report_list_templates tool: returns available templates with their JSON schemas + +Implement report_generate tool: accepts template name + format + structured data, produces output file + +Rendering stack: +PDF: React-PDF (@react-pdf/renderer) +PPTX: pptxgenjs +Charts: chart.js with chartjs-node-canvas (server-side PNG/SVG rendering) + +Built-in template: MonthlyReportData with title, period, summary metrics, charts (bar/line/pie), and tables + +Template schema validation before rendering (fail fast with clear error messages) +B) Agent-generated code reports +Agent writes Python or JavaScript code that runs inside the sandbox to produce visualizations and reports. + + +Implement report_execute_code tool: accepts language, code, optional dependencies + +Execution flow: +Install dependencies (pip install / npm install) if specified +Write code to temp file +Execute with 60-second timeout +Glob /workspace/output/*.{png,svg,pdf,pptx,csv,xlsx} for output files + +Pre-installed Python libraries in sandbox image: matplotlib, pandas, numpy, seaborn + +Available JS libraries: chart.js + chartjs-node-canvas, d3 +Output format matrix +Format Template approach Code approach +PDF React-PDF matplotlib / reportlab +PPTX pptxgenjs python-pptx +PNG chart.js canvas matplotlib / chart.js +SVG chart.js canvas matplotlib / D3 +CSV built-in pandas +XLSX exceljs openpyxl +File delivery + +Files saved to /workspace/output/ in sandbox + +Orchestrator copies files out via sandbox file API + +Upload to temporary storage (S3-compatible or local filesystem) + +Return download URLs to the client + +Channel-specific delivery: +Web: download link in chat message +Slack: file upload to thread via files.upload +WhatsApp: media message +Sandbox Dockerfile updates + +Install Python report dependencies: matplotlib, pandas, numpy, seaborn, reportlab, python-pptx, openpyxl + + +Install Node report dependencies: @react-pdf/renderer, pptxgenjs, chart.js, chartjs-node-canvas, exceljs, d3 + + +Create /workspace/output/ directory with sandbox user write permissions + +skills/reports + +orchestrator + +sandbox + +Motivation +Agents need to produce deliverables beyond text -- PDF reports, presentations, charts, data exports. This is essential for enterprise use cases: monthly performance reports, data analysis summaries, executive presentations, financial exports. The report skill makes agents productive for knowledge work that requires formatted, shareable output. + +Affected package(s) +skills/reports, orchestrator, sandbox + +Alternatives considered +Code-only approach (no templates) -- less consistent output quality; templates guarantee a professional baseline. +Third-party report generation service -- adds external dependency, latency, and cost; in-sandbox generation is self-contained. +Markdown-only output -- insufficient for enterprise needs; stakeholders expect PDF/PPTX. \ No newline at end of file diff --git a/infra/openshell/Dockerfile b/infra/openshell/Dockerfile index cb5ac83..78bca07 100644 --- a/infra/openshell/Dockerfile +++ b/infra/openshell/Dockerfile @@ -118,6 +118,9 @@ RUN npm install -g @mariozechner/pi-coding-agent # The CLI reads SLACK_TOKEN from the environment (injected via .env by the orchestrator). RUN npm install -g agent-slack +# Install Node report libraries available to agent-generated code. +RUN npm install -g chart.js chartjs-node-canvas d3 exceljs + # Copy extension manifest and install script before switching to sandbox user COPY packages/agents/extensions.json /tmp/extensions.json COPY infra/openshell/scripts/install-extensions.mjs /tmp/install-extensions.mjs From 29e5831861012e6fccf59c41dc69f3e53d637b1f Mon Sep 17 00:00:00 2001 From: shanvit Date: Thu, 2 Apr 2026 13:30:43 +0530 Subject: [PATCH 09/12] chore: implemented report generation skills and hydartion error fix on files page --- apps/web/src/app/(application)/files/page.tsx | 22 +-- .../artifacts/[filename]/route.ts | 4 +- apps/web/src/utils/file-utils.tsx | 3 +- packages/agents/src/pi.agent.ts | 9 +- packages/agents/src/pi/tools.ts | 11 +- packages/gateway/src/app.ts | 165 ++++++++++++++++++ packages/gateway/src/session-manager.ts | 70 +++++++- packages/skills/reports/src/renderers/csv.ts | 7 +- packages/skills/reports/src/renderers/pdf.ts | 8 +- .../reports/src/templates/monthly-report.ts | 4 +- packages/skills/reports/src/tools.ts | 46 +++-- 11 files changed, 301 insertions(+), 48 deletions(-) diff --git a/apps/web/src/app/(application)/files/page.tsx b/apps/web/src/app/(application)/files/page.tsx index 87c33b5..90d2f44 100644 --- a/apps/web/src/app/(application)/files/page.tsx +++ b/apps/web/src/app/(application)/files/page.tsx @@ -1,6 +1,6 @@ "use client" -import { useCallback, useRef, useState } from "react" +import React, { useCallback, useRef, useState } from "react" import { toast } from "sonner" // UI Components @@ -354,16 +354,18 @@ const FilesPage = () => { {breadcrumbs.map((entry, i) => ( - + {i > 0 && } - {i === breadcrumbs.length - 1 ? ( - {entry.name} - ) : ( - navigateToBreadcrumb(entry)}> - {entry.name} - - )} - + + {i === breadcrumbs.length - 1 ? ( + {entry.name} + ) : ( + navigateToBreadcrumb(entry)}> + {entry.name} + + )} + + ))} diff --git a/apps/web/src/app/api/conversations/[conversationid]/artifacts/[filename]/route.ts b/apps/web/src/app/api/conversations/[conversationid]/artifacts/[filename]/route.ts index 15f6502..8cd4e60 100644 --- a/apps/web/src/app/api/conversations/[conversationid]/artifacts/[filename]/route.ts +++ b/apps/web/src/app/api/conversations/[conversationid]/artifacts/[filename]/route.ts @@ -32,7 +32,9 @@ export async function GET( // Proxy to gateway try { const gatewayUrl = `${GATEWAY_URL}/api/v1/sessions/${conversationid}/artifacts/${encodeURIComponent(filename)}${queryString}` - const response = await fetch(gatewayUrl) + const response = await fetch(gatewayUrl, { + headers: { cookie: reqheaders.get("cookie") ?? "" }, + }) if (!response.ok) { return NextResponse.json({ error: "Artifact not found" }, { status: response.status }) diff --git a/apps/web/src/utils/file-utils.tsx b/apps/web/src/utils/file-utils.tsx index d890120..256864a 100644 --- a/apps/web/src/utils/file-utils.tsx +++ b/apps/web/src/utils/file-utils.tsx @@ -45,7 +45,8 @@ export const isPreviewable = (mediatype: string): boolean => { mediatype === "text/plain" || mediatype === "text/markdown" || mediatype === "text/csv" || - mediatype === "application/json" + mediatype === "application/json" || + mediatype === "application/pdf" ) } diff --git a/packages/agents/src/pi.agent.ts b/packages/agents/src/pi.agent.ts index f2c3e1e..b5d76a6 100644 --- a/packages/agents/src/pi.agent.ts +++ b/packages/agents/src/pi.agent.ts @@ -11,7 +11,12 @@ import { createLogger } from "@openzosma/logger" import { bootstrapMemory } from "@openzosma/memory" import { DEFAULT_SYSTEM_PROMPT } from "./pi/config.js" import { resolveModel } from "./pi/model.js" -import { createDefaultTools, createListDatabaseSchemasTool, createQueryDatabaseTool, createReportTools } from "./pi/tools.js" +import { + createDefaultTools, + createListDatabaseSchemasTool, + createQueryDatabaseTool, + createReportTools, +} from "./pi/tools.js" import type { AgentMessage, AgentProvider, AgentSession, AgentSessionOpts, AgentStreamEvent } from "./types.js" const log = createLogger({ component: "agents" }) @@ -52,7 +57,7 @@ class PiAgentSession implements AgentSession { memoryDir: opts.memoryDir, }) const toolList = [...createDefaultTools(opts.workspaceDir, opts.toolsEnabled)] - const reportTools = createReportTools(opts.toolsEnabled) + const reportTools = createReportTools(opts.toolsEnabled, opts.workspaceDir) const customTools = [ ...reportTools, ...(opts.dbPool ? [createQueryDatabaseTool(opts.dbPool), createListDatabaseSchemasTool(opts.dbPool)] : []), diff --git a/packages/agents/src/pi/tools.ts b/packages/agents/src/pi/tools.ts index 29dc249..d059e6e 100644 --- a/packages/agents/src/pi/tools.ts +++ b/packages/agents/src/pi/tools.ts @@ -71,12 +71,15 @@ export const createDefaultTools = (workspaceDir: string, toolsEnabled?: string[] * These go in `customTools` when calling createAgentSession. * * @param toolsEnabled - Optional allow-list of tool names. If omitted, all report tools are returned. + * @param workspaceDir - Workspace root; report output will go to /output. + * Defaults to /workspace/output when omitted (sandbox mode). */ -export const createReportTools = (toolsEnabled?: string[]): ToolDefinition[] => { +export const createReportTools = (toolsEnabled?: string[], workspaceDir?: string): ToolDefinition[] => { + const outputDir = workspaceDir ? `${workspaceDir}/output` : undefined const allTools = [ - { name: "report_list_templates" as CustomToolName, tool: createReportListTemplatesTool() }, - { name: "report_generate" as CustomToolName, tool: createReportGenerateTool() }, - { name: "report_execute_code" as CustomToolName, tool: createReportExecuteCodeTool() }, + { name: "report_list_templates" as CustomToolName, tool: createReportListTemplatesTool({ outputDir }) }, + { name: "report_generate" as CustomToolName, tool: createReportGenerateTool({ outputDir }) }, + { name: "report_execute_code" as CustomToolName, tool: createReportExecuteCodeTool({ outputDir }) }, ] if (!toolsEnabled || toolsEnabled.length === 0) { diff --git a/packages/gateway/src/app.ts b/packages/gateway/src/app.ts index 7acf6fd..172d0e0 100644 --- a/packages/gateway/src/app.ts +++ b/packages/gateway/src/app.ts @@ -1,4 +1,6 @@ import { createHash, randomBytes } from "node:crypto" +import { createReadStream, existsSync, mkdirSync, readdirSync, statSync } from "node:fs" +import { join, resolve } from "node:path" import { buildDefaultAgentCard } from "@openzosma/a2a" import type { Auth } from "@openzosma/auth" import type { Role } from "@openzosma/auth" @@ -79,10 +81,173 @@ export const createApp = ( // File management routes (require orchestrator for sandbox filesystem access) // ----------------------------------------------------------------------- + // MIME types for agent-generated artifacts (used in local-mode file routes + // and the session artifact routes below). + const ARTIFACT_MIME_MAP: Record = { + png: "image/png", + svg: "image/svg+xml", + pdf: "application/pdf", + pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation", + csv: "text/csv", + xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + txt: "text/plain", + json: "application/json", + } + if (orchestrator) { app.route("/api/v1/files", createFileRoutes({ orchestrator })) + } else { + // Local mode: serve files from workspace/user-files/ai-generated/. + // Files are copied here by scanOutputDir whenever the agent generates an artifact. + + const localUserFilesDir = (): string => { + const root = resolve(process.env.OPENZOSMA_WORKSPACE ?? join(process.cwd(), "workspace")) + const dir = join(root, "user-files", "ai-generated") + mkdirSync(dir, { recursive: true }) + return dir + } + + const LOCAL_MIME_MAP: Record = { + png: "image/png", + svg: "image/svg+xml", + pdf: "application/pdf", + pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation", + csv: "text/csv", + xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + txt: "text/plain", + json: "application/json", + } + + const scanLocalFiles = (dir: string) => + existsSync(dir) + ? readdirSync(dir) + .filter((f) => LOCAL_MIME_MAP[f.split(".").pop() ?? ""]) + .map((filename) => { + const ext = filename.split(".").pop() ?? "" + return { + name: filename, + path: `/ai-generated/${filename}`, + isFolder: false, + mimeType: LOCAL_MIME_MAP[ext] ?? "application/octet-stream", + sizeBytes: statSync(join(dir, filename)).size, + modifiedAt: statSync(join(dir, filename)).mtime.toISOString(), + } + }) + : [] + + app.get("/api/v1/files/tree", requirePermission("files", "read"), (c) => { + const dir = localUserFilesDir() + const files = scanLocalFiles(dir) + const entries = + files.length > 0 + ? [ + { + name: "ai-generated", + path: "/ai-generated", + isFolder: true, + mimeType: null, + sizeBytes: 0, + modifiedAt: new Date().toISOString(), + children: files, + }, + ] + : [] + return c.json({ entries }) + }) + + app.get("/api/v1/files/list", requirePermission("files", "read"), (c) => { + const dir = localUserFilesDir() + return c.json({ entries: scanLocalFiles(dir) }) + }) + + app.get("/api/v1/files/download", requirePermission("files", "read"), (c) => { + const filePath = c.req.query("path") + if (!filePath) return c.json({ error: "path query parameter is required" }, 400) + + const dir = localUserFilesDir() + // path is like /ai-generated/filename.pdf — strip the folder prefix + const filename = filePath.replace(/^\/ai-generated\//, "") + const fullPath = join(dir, filename) + + if (!existsSync(fullPath)) return c.json({ error: "File not found" }, 404) + + const ext = filename.split(".").pop() ?? "" + const contentType = LOCAL_MIME_MAP[ext] ?? "application/octet-stream" + const stat = statSync(fullPath) + const download = c.req.query("download") === "true" + + c.header("Content-Type", contentType) + c.header("Content-Length", String(stat.size)) + c.header("Cache-Control", "private, max-age=3600") + if (download) c.header("Content-Disposition", `attachment; filename="${filename}"`) + + const stream = createReadStream(fullPath) + return c.body(stream as unknown as ReadableStream) + }) } + // ----------------------------------------------------------------------- + // Session artifact routes (local mode — serve files from session output dir) + // ----------------------------------------------------------------------- + + app.get("/api/v1/sessions/:id/artifacts/:filename", requirePermission("sessions", "read"), (c) => { + const sessionId = c.req.param("id") + const filename = c.req.param("filename") + + const workspaceDir = sessionManager.getSessionWorkspaceDir(sessionId) + if (!workspaceDir) { + return c.json({ error: "Session not found or not in local mode" }, 404) + } + + const filePath = join(workspaceDir, "output", filename) + if (!existsSync(filePath)) { + return c.json({ error: "Artifact not found" }, 404) + } + + const stat = statSync(filePath) + const ext = filename.split(".").pop() ?? "" + const contentType = ARTIFACT_MIME_MAP[ext] ?? "application/octet-stream" + const download = c.req.query("download") === "true" + + c.header("Content-Type", contentType) + c.header("Content-Length", String(stat.size)) + c.header("Cache-Control", "private, max-age=3600") + if (download) { + c.header("Content-Disposition", `attachment; filename="${filename}"`) + } + + // Stream the file to avoid loading it fully into memory + const stream = createReadStream(filePath) + return c.body(stream as unknown as ReadableStream) + }) + + app.get("/api/v1/sessions/:id/artifacts", requirePermission("sessions", "read"), (c) => { + const sessionId = c.req.param("id") + const workspaceDir = sessionManager.getSessionWorkspaceDir(sessionId) + if (!workspaceDir) { + return c.json({ artifacts: [] }) + } + + const outputDir = join(workspaceDir, "output") + if (!existsSync(outputDir)) { + return c.json({ artifacts: [] }) + } + + const TRACKED_EXTS = new Set(Object.keys(ARTIFACT_MIME_MAP)) + const artifacts = readdirSync(outputDir) + .filter((f) => TRACKED_EXTS.has(f.split(".").pop() ?? "")) + .map((filename) => { + const ext = filename.split(".").pop() ?? "" + return { + filename, + mediatype: ARTIFACT_MIME_MAP[ext] ?? "application/octet-stream", + sizebytes: statSync(join(outputDir, filename)).size, + } + }) + + return c.json({ artifacts }) + }) + // ----------------------------------------------------------------------- // Session routes // ----------------------------------------------------------------------- diff --git a/packages/gateway/src/session-manager.ts b/packages/gateway/src/session-manager.ts index 590f25e..0bacf64 100644 --- a/packages/gateway/src/session-manager.ts +++ b/packages/gateway/src/session-manager.ts @@ -1,6 +1,6 @@ import { randomUUID } from "node:crypto" import { EventEmitter } from "node:events" -import { mkdirSync, symlinkSync, writeFileSync } from "node:fs" +import { copyFileSync, existsSync, mkdirSync, readdirSync, statSync, symlinkSync, writeFileSync } from "node:fs" import { dirname, join, resolve } from "node:path" import type { AgentProvider, AgentSession } from "@openzosma/agents" import { PiAgentProvider } from "@openzosma/agents" @@ -241,6 +241,14 @@ export class SessionManager { return this.sessions.get(id)?.session } + /** + * Return the workspace directory for a local-mode session, or undefined + * when running in orchestrator mode or the session does not exist. + */ + getSessionWorkspaceDir(id: string): string | undefined { + return this.sessions.get(id)?.workspaceDir + } + deleteSession(id: string): boolean { if (this.orchestrator) { const session = this.sessions.get(id) @@ -578,6 +586,8 @@ export class SessionManager { let lastAssistantText = "" let lastMessageId: string | undefined const emitter = this.getEmitter(sessionId) + // Track files already seen so we only emit each artifact once per message. + const seenOutputFiles = new Set() for await (const event of agentSession.sendMessage(augmentedContent, signal)) { const gatewayEvent: GatewayEvent = event as GatewayEvent @@ -591,6 +601,17 @@ export class SessionManager { emitter.emit("event", gatewayEvent) yield gatewayEvent + + // After each tool call completes, scan the output directory for new files + // and emit a file_output event so the frontend can display download links. + if (event.type === "tool_call_end") { + const newArtifacts = this.scanOutputDir(workspaceDir, seenOutputFiles) + if (newArtifacts.length > 0) { + const fileEvent: GatewayEvent = { type: "file_output", artifacts: newArtifacts } + emitter.emit("event", fileEvent) + yield fileEvent + } + } } // Store assistant message for session history @@ -605,6 +626,53 @@ export class SessionManager { } } + /** + * Scan workspaceDir/output for files and return FileArtifact metadata. + * Used in local mode to emit file_output events after tool calls. + */ + private scanOutputDir(workspaceDir: string, seenFiles: Set): FileArtifact[] { + const outputDir = join(workspaceDir, "output") + if (!existsSync(outputDir)) return [] + + const MIME_MAP: Record = { + png: "image/png", + svg: "image/svg+xml", + pdf: "application/pdf", + pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation", + csv: "text/csv", + xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + } + const TRACKED_EXTS = new Set(Object.keys(MIME_MAP)) + + // Copy new artifacts to the central user-files area so the Files page can list them + const workspaceRoot = resolve(process.env.OPENZOSMA_WORKSPACE ?? join(process.cwd(), "workspace")) + const userFilesDir = join(workspaceRoot, "user-files", "ai-generated") + mkdirSync(userFilesDir, { recursive: true }) + + const newArtifacts: FileArtifact[] = [] + for (const filename of readdirSync(outputDir)) { + if (seenFiles.has(filename)) continue + const ext = filename.split(".").pop() ?? "" + if (!TRACKED_EXTS.has(ext)) continue + const filepath = join(outputDir, filename) + const sizebytes = statSync(filepath).size + seenFiles.add(filename) + newArtifacts.push({ + filename, + mediatype: MIME_MAP[ext] ?? "application/octet-stream", + sizebytes, + }) + + // Non-fatal: artifact card in chat still works via the session artifact route + try { + copyFileSync(filepath, join(userFilesDir, filename)) + } catch { + /* ignore */ + } + } + return newArtifacts + } + /** * Decode a data URL into a Buffer and MIME type. * diff --git a/packages/skills/reports/src/renderers/csv.ts b/packages/skills/reports/src/renderers/csv.ts index 056ce35..8b9b83c 100644 --- a/packages/skills/reports/src/renderers/csv.ts +++ b/packages/skills/reports/src/renderers/csv.ts @@ -40,12 +40,7 @@ export const renderCsv = async (data: MonthlyReportData): Promise => { sections.push( renderTable( ["label", "value", "unit", "change"], - data.metrics.map((m) => [ - m.label, - String(m.value), - m.unit ?? "", - m.change !== undefined ? String(m.change) : "", - ]), + data.metrics.map((m) => [m.label, String(m.value), m.unit ?? "", m.change !== undefined ? String(m.change) : ""]), ), ) diff --git a/packages/skills/reports/src/renderers/pdf.ts b/packages/skills/reports/src/renderers/pdf.ts index a4c25ce..34006f9 100644 --- a/packages/skills/reports/src/renderers/pdf.ts +++ b/packages/skills/reports/src/renderers/pdf.ts @@ -1,10 +1,8 @@ -import ReactPDF from "@react-pdf/renderer" +import { Document, Image, Page, StyleSheet, Text, View, renderToBuffer } from "@react-pdf/renderer" import React from "react" import type { MonthlyReportData, RenderOpts } from "../templates/types.js" import { renderChart } from "./chart.js" -const { Document, Page, View, Text, Image, StyleSheet, renderToBuffer } = ReactPDF - const styles = StyleSheet.create({ page: { padding: 40, @@ -114,9 +112,7 @@ export const renderPdf = async (data: MonthlyReportData, _opts?: RenderOpts): Pr ), ) - page1Rows.push( - React.createElement(View, { key: "metricsTable" }, metricHeaderRow, ...metricDataRows), - ) + page1Rows.push(React.createElement(View, { key: "metricsTable" }, metricHeaderRow, ...metricDataRows)) } children.push(React.createElement(Page, { key: "p1", size: "A4", style: styles.page }, ...page1Rows)) diff --git a/packages/skills/reports/src/templates/monthly-report.ts b/packages/skills/reports/src/templates/monthly-report.ts index 04cd1df..4d2f994 100644 --- a/packages/skills/reports/src/templates/monthly-report.ts +++ b/packages/skills/reports/src/templates/monthly-report.ts @@ -76,7 +76,9 @@ const renderMonthlyReport = async ( return renderXlsx(data, opts) case "png": case "svg": - throw new Error(`Format '${format}' is not supported by the monthly-report template directly. Use report_execute_code to generate charts as standalone image files.`) + throw new Error( + `Format '${format}' is not supported by the monthly-report template directly. Use report_execute_code to generate charts as standalone image files.`, + ) default: { const _exhaustive: never = format throw new Error(`Unsupported format: ${String(_exhaustive)}`) diff --git a/packages/skills/reports/src/tools.ts b/packages/skills/reports/src/tools.ts index b33996f..9403a6c 100644 --- a/packages/skills/reports/src/tools.ts +++ b/packages/skills/reports/src/tools.ts @@ -16,7 +16,7 @@ const textResult = (text: string): AgentToolResult => ({ details: {}, }) -const OUTPUT_DIR = "/workspace/output" +const DEFAULT_OUTPUT_DIR = "/workspace/output" const MIME_MAP: Record = { png: "image/png", @@ -37,7 +37,7 @@ const OUTPUT_EXTENSIONS = new Set(["png", "svg", "pdf", "pptx", "csv", "xlsx"]) * Returns a JSON array of all registered report templates, including their * name, label, description, and supported output formats. */ -export const createReportListTemplatesTool = (): ToolDefinition => ({ +export const createReportListTemplatesTool = (_opts?: { outputDir?: string }): ToolDefinition => ({ name: "report_list_templates", label: "List Report Templates", description: "List all available report templates with their names, descriptions, and supported formats.", @@ -58,16 +58,19 @@ export const createReportListTemplatesTool = (): ToolDefinition => ({ * Create the report_generate tool. * * Validates the input data against the template's TypeBox schema, renders - * the report, writes it to /workspace/output/, and returns the file path + * the report, writes it to the output directory, and returns the file path * and size. + * + * @param opts.outputDir - Override the output directory (default: /workspace/output). */ -export const createReportGenerateTool = (): ToolDefinition => ({ +export const createReportGenerateTool = (opts?: { outputDir?: string }): ToolDefinition => ({ name: "report_generate", label: "Generate Report", description: - "Generate a report from a registered template and structured data. " + - "Returns the file path and size of the generated report.", - promptSnippet: "report_generate(template, format, data) — render a report from a template", + "Generate a report or chart from a registered template and structured data. " + + "Use this tool (not matplotlib or custom code) whenever the user asks for a chart, graph, or report. " + + "Supports pdf, png, svg, xlsx, csv formats. Returns the file path and size of the generated artifact.", + promptSnippet: "report_generate(template, format, data) — preferred way to render charts and reports", parameters: Type.Object({ template: Type.String({ description: "Template name, e.g. 'monthly-report'." }), format: Type.Union( @@ -118,12 +121,13 @@ export const createReportGenerateTool = (): ToolDefinition => ({ ) } - mkdirSync(OUTPUT_DIR, { recursive: true }) + const outputDir = opts?.outputDir ?? DEFAULT_OUTPUT_DIR + mkdirSync(outputDir, { recursive: true }) - const buffer = await template.render(p.format, p.data as unknown as MonthlyReportData, { outputDir: OUTPUT_DIR }) + const buffer = await template.render(p.format, p.data as unknown as MonthlyReportData, { outputDir }) const filename = p.outputFilename ?? `${p.template}-${Date.now()}.${p.format}` - const outPath = `${OUTPUT_DIR}/${filename}` + const outPath = `${outputDir}/${filename}` writeFileSync(outPath, buffer) const sizeBytes = statSync(outPath).size @@ -139,15 +143,15 @@ export const createReportGenerateTool = (): ToolDefinition => ({ * inside /workspace, and returns paths to any generated output files together * with captured stdout. */ -export const createReportExecuteCodeTool = (): ToolDefinition => ({ +export const createReportExecuteCodeTool = (opts?: { outputDir?: string }): ToolDefinition => ({ name: "report_execute_code", label: "Execute Report Code", description: - "Execute Python or JavaScript code to generate charts, reports, or data visualizations. " + - "Code should save output files to /workspace/output/. " + + "Fallback tool: execute Python or JavaScript code to generate charts or reports when report_generate cannot satisfy the request. " + + "Code MUST save all output files to /workspace/output/ — files saved elsewhere will not appear as artifacts. " + "Returns file paths and stdout.", promptSnippet: - "report_execute_code(language, code, dependencies?, outputDir?) — run code that generates report files", + "report_execute_code(language, code, dependencies?, outputDir?) — fallback: run custom code that saves files to /workspace/output/", parameters: Type.Object({ language: Type.Union([Type.Literal("python"), Type.Literal("javascript")], { description: "Runtime to use.", @@ -168,7 +172,7 @@ export const createReportExecuteCodeTool = (): ToolDefinition => ({ outputDir?: string } - const outputDir = p.outputDir ?? OUTPUT_DIR + const outputDir = p.outputDir ?? opts?.outputDir ?? DEFAULT_OUTPUT_DIR mkdirSync(outputDir, { recursive: true }) // Install dependencies @@ -198,7 +202,17 @@ export const createReportExecuteCodeTool = (): ToolDefinition => ({ // Execute let stdout = "" try { - const runtime = p.language === "python" ? "python3" : "node" + const runtime = + p.language === "python" + ? (() => { + try { + execFileSync("python3", ["--version"]) + return "python3" + } catch { + return "python" + } + })() + : "node" const result = execFileSync(runtime, [scriptPath], { timeout: 60000, cwd: "/workspace", From f7b46061b2c07a0760b111017dc28e07118bd250 Mon Sep 17 00:00:00 2001 From: shanvit Date: Thu, 2 Apr 2026 13:42:02 +0530 Subject: [PATCH 10/12] chore: broken test fixed --- .../reports/src/renderers/chart.test.ts | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/skills/reports/src/renderers/chart.test.ts b/packages/skills/reports/src/renderers/chart.test.ts index c62ad0b..7ad1355 100644 --- a/packages/skills/reports/src/renderers/chart.test.ts +++ b/packages/skills/reports/src/renderers/chart.test.ts @@ -1,7 +1,27 @@ -import { describe, expect, it } from "vitest" +import { beforeEach, describe, expect, it, vi } from "vitest" + +// Mock chartjs-node-canvas before importing renderChart so the native canvas +// binary is never loaded. CI runners do not have the system libraries (Cairo, +// libpng) required to compile canvas@2.x, causing a hard module-not-found +// error when the real binding is required. +vi.mock("chartjs-node-canvas", () => { + const PNG_HEADER = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]) + + const ChartJSNodeCanvas = vi.fn().mockImplementation(() => ({ + renderToBuffer: vi.fn().mockResolvedValue(PNG_HEADER), + renderToBufferSync: vi.fn().mockReturnValue(Buffer.from("", "utf-8")), + })) + + return { ChartJSNodeCanvas } +}) + import { renderChart } from "./chart.js" describe("renderChart", () => { + beforeEach(() => { + vi.clearAllMocks() + }) + it("renders a bar chart and returns a Buffer with PNG magic bytes", async () => { const buf = await renderChart({ type: "bar", @@ -45,4 +65,18 @@ describe("renderChart", () => { expect(buf).toBeInstanceOf(Buffer) expect(buf.length).toBeGreaterThan(0) }) + + it("renders an SVG when format is svg", async () => { + const buf = await renderChart( + { + type: "bar", + title: "SVG Chart", + labels: ["X"], + datasets: [{ label: "Y", data: [1] }], + }, + "svg", + ) + expect(buf).toBeInstanceOf(Buffer) + expect(buf.toString()).toContain(" Date: Thu, 2 Apr 2026 18:39:36 +0530 Subject: [PATCH 11/12] chore: file delete for unwanted dev --- docs/CURRENT-TASK.md | 84 -------------------------------------------- 1 file changed, 84 deletions(-) delete mode 100644 docs/CURRENT-TASK.md diff --git a/docs/CURRENT-TASK.md b/docs/CURRENT-TASK.md deleted file mode 100644 index 0f84044..0000000 --- a/docs/CURRENT-TASK.md +++ /dev/null @@ -1,84 +0,0 @@ -Description -Implement the report generation skill at packages/skills/reports/ (currently an empty placeholder: export {}). This skill enables agents to produce formatted deliverables -- PDF reports, PPTX presentations, charts, and data exports. - -Two approaches are supported simultaneously: - -A) Template-based reports -Agent produces structured JSON matching a predefined template schema. The skill renders it into the requested format. - - -Implement report_list_templates tool: returns available templates with their JSON schemas - -Implement report_generate tool: accepts template name + format + structured data, produces output file - -Rendering stack: -PDF: React-PDF (@react-pdf/renderer) -PPTX: pptxgenjs -Charts: chart.js with chartjs-node-canvas (server-side PNG/SVG rendering) - -Built-in template: MonthlyReportData with title, period, summary metrics, charts (bar/line/pie), and tables - -Template schema validation before rendering (fail fast with clear error messages) -B) Agent-generated code reports -Agent writes Python or JavaScript code that runs inside the sandbox to produce visualizations and reports. - - -Implement report_execute_code tool: accepts language, code, optional dependencies - -Execution flow: -Install dependencies (pip install / npm install) if specified -Write code to temp file -Execute with 60-second timeout -Glob /workspace/output/*.{png,svg,pdf,pptx,csv,xlsx} for output files - -Pre-installed Python libraries in sandbox image: matplotlib, pandas, numpy, seaborn - -Available JS libraries: chart.js + chartjs-node-canvas, d3 -Output format matrix -Format Template approach Code approach -PDF React-PDF matplotlib / reportlab -PPTX pptxgenjs python-pptx -PNG chart.js canvas matplotlib / chart.js -SVG chart.js canvas matplotlib / D3 -CSV built-in pandas -XLSX exceljs openpyxl -File delivery - -Files saved to /workspace/output/ in sandbox - -Orchestrator copies files out via sandbox file API - -Upload to temporary storage (S3-compatible or local filesystem) - -Return download URLs to the client - -Channel-specific delivery: -Web: download link in chat message -Slack: file upload to thread via files.upload -WhatsApp: media message -Sandbox Dockerfile updates - -Install Python report dependencies: matplotlib, pandas, numpy, seaborn, reportlab, python-pptx, openpyxl - - -Install Node report dependencies: @react-pdf/renderer, pptxgenjs, chart.js, chartjs-node-canvas, exceljs, d3 - - -Create /workspace/output/ directory with sandbox user write permissions - -skills/reports - -orchestrator - -sandbox - -Motivation -Agents need to produce deliverables beyond text -- PDF reports, presentations, charts, data exports. This is essential for enterprise use cases: monthly performance reports, data analysis summaries, executive presentations, financial exports. The report skill makes agents productive for knowledge work that requires formatted, shareable output. - -Affected package(s) -skills/reports, orchestrator, sandbox - -Alternatives considered -Code-only approach (no templates) -- less consistent output quality; templates guarantee a professional baseline. -Third-party report generation service -- adds external dependency, latency, and cost; in-sandbox generation is self-contained. -Markdown-only output -- insufficient for enterprise needs; stakeholders expect PDF/PPTX. \ No newline at end of file From c5324e0cae9844f97322fdffe8b16591161769c8 Mon Sep 17 00:00:00 2001 From: shanvit Date: Fri, 3 Apr 2026 12:28:11 +0530 Subject: [PATCH 12/12] chore: docker file changes --- infra/openshell/Dockerfile | 78 ++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 24 deletions(-) diff --git a/infra/openshell/Dockerfile b/infra/openshell/Dockerfile index 78bca07..9395f9c 100644 --- a/infra/openshell/Dockerfile +++ b/infra/openshell/Dockerfile @@ -17,10 +17,28 @@ # ============================================================================= # --------------------------------------------------------------------------- -# Stage 1: Build sandbox-server and produce a deployable bundle +# Stage 1: Build sandbox-server and produce a deployable bundle. +# Also pre-builds all native npm globals here so the runtime stage does not +# need a C/C++ toolchain. # --------------------------------------------------------------------------- FROM node:22-slim AS builder +# Build-time system dependencies: +# - build-essential / g++ / make / pkg-config: required by node-gyp for native modules +# - *-dev packages: header files needed to compile canvas (cairo, gif, jpeg, pango, rsvg) +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + g++ \ + libcairo2-dev \ + libgif-dev \ + libjpeg-dev \ + libpango1.0-dev \ + librsvg2-dev \ + make \ + pkg-config \ + python3 \ + && rm -rf /var/lib/apt/lists/* + RUN corepack enable && corepack prepare pnpm@10.32.1 --activate WORKDIR /build @@ -53,32 +71,46 @@ RUN pnpm --filter @openzosma/sandbox-server deploy /deploy --prod --legacy # Copy built dist into the deploy directory RUN cp -r packages/sandbox-server/dist /deploy/dist +# Pre-build all global npm packages that contain native modules or are large. +# Installing here (with the toolchain present) means the runtime stage only +# needs to COPY the pre-compiled /usr/local/lib/node_modules directory — +# no compiler required at runtime. +RUN npm install -g \ + @mariozechner/pi-coding-agent \ + agent-slack \ + chart.js \ + chartjs-node-canvas \ + d3 \ + exceljs + # --------------------------------------------------------------------------- # Stage 2: Runtime # --------------------------------------------------------------------------- FROM node:22-slim -# Install runtime dependencies and developer tools. -# iproute2 is required by the OpenShell sandbox supervisor for network namespace creation. -# python3-venv provides virtualenv support for isolated Python environments. -# tree, jq, wget, less, unzip, zip are general-purpose CLI tools the agent can use. -# make + g++ are required for native npm modules that use node-gyp. -# Node.js and npm are already present from the node:22-slim base image. +# Runtime system dependencies only — no compiler toolchain, no *-dev headers. +# +# Shared libraries required by pre-compiled native modules (e.g. canvas): +# libcairo2, libgif7, libjpeg62-turbo, libpango-1.0-0, libpangocairo-1.0-0, +# librsvg2-2 — these are the runtime counterparts of the *-dev packages used +# in the builder stage. +# +# iproute2: required by the OpenShell sandbox supervisor for network namespace creation. +# python3 / python3-pip / python3-venv: agent-generated Python code + report generation. +# tini: PID 1 / signal handling. +# git, curl, wget, jq, less, tree, unzip, zip: general-purpose CLI tools for the agent. RUN apt-get update && apt-get install -y --no-install-recommends \ - build-essential \ curl \ - g++ \ git \ iproute2 \ jq \ less \ - libcairo2-dev \ - libgif-dev \ - libjpeg-dev \ - libpango1.0-dev \ - librsvg2-dev \ - make \ - pkg-config \ + libcairo2 \ + libgif7 \ + libjpeg62-turbo \ + libpango-1.0-0 \ + libpangocairo-1.0-0 \ + librsvg2-2 \ python3 \ python3-pip \ python3-venv \ @@ -112,14 +144,12 @@ WORKDIR /app # Copy the self-contained deploy bundle (node_modules + dist, no symlinks) COPY --from=builder /deploy ./ -RUN npm install -g @mariozechner/pi-coding-agent - -# Install agent-slack CLI so the agent can query Slack from inside the sandbox. -# The CLI reads SLACK_TOKEN from the environment (injected via .env by the orchestrator). -RUN npm install -g agent-slack - -# Install Node report libraries available to agent-generated code. -RUN npm install -g chart.js chartjs-node-canvas d3 exceljs +# Copy pre-compiled global npm packages from the builder stage. +# All native modules (e.g. canvas inside chartjs-node-canvas) were compiled +# there with the full toolchain. The runtime stage needs only the shared libs +# (installed above), not the compiler. +COPY --from=builder /usr/local/lib/node_modules /usr/local/lib/node_modules +COPY --from=builder /usr/local/bin /usr/local/bin # Copy extension manifest and install script before switching to sandbox user COPY packages/agents/extensions.json /tmp/extensions.json